23 from __future__ 
import absolute_import, division, print_function
    24 from past.builtins 
import long
    26 from io 
import BytesIO
    27 from socket 
import gaierror
    37 from .footprints 
import createFootprintsTable
    42 except ImportError 
as e:
    43     raise RuntimeError(
"Cannot import firefly_client: %s" % (e))
    44 from ws4py.client 
import HandshakeError
    50         Exception.__init__(self, str)
    54     """Return the version of firefly_client in use, as a string"""    55     return(firefly_client.__version__)
    59     """Device to talk to a firefly display"""    62     def __handleCallbacks(event):
    63         if 'type' in event[
'data']:
    64             if event[
'data'][
'type'] == 
'AREA_SELECT':
    65                 lsst.log.debug(
'*************area select')
    66                 pParams = {
'URL': 
'http://web.ipac.caltech.edu/staff/roby/demo/wise-m51-band2.fits',
    70                 _fireflyClient.show_fits(fileOnServer=
None, plot_id=plot_id, additionalParams=pParams)
    72         lsst.log.debug(
"Callback event info: {}".
format(event))
    74         data = dict((_.split(
'=') 
for _ 
in event.get(
'data', {}).split(
'&')))
    75         if data.get(
'type') == 
"POINT":
    76             lsst.log.debug(
"Event Received: %s" % data.get(
'id'))
    78     def __init__(self, display, verbose=False, url=None,
    79                  name=None, *args, **kwargs):
    80         virtualDevice.DisplayImpl.__init__(self, display, verbose)
    83             print(
"Opening firefly device %s" % (self.display.frame 
if self.display 
else "[None]"))
    86         if not _fireflyClient:
    89             html_file = kwargs.get(
'html_file',
    90                                    os.environ.get(
'FIREFLY_HTML', 
'slate.html'))
    92                 if ((
'fireflyLabExtension' in os.environ) 
and    93                         (
'fireflyURLLab' in os.environ)):
    94                     url = os.environ[
'fireflyURLLab']
    95                     start_tab = kwargs.get(
'start_tab', 
True)
    96                     start_browser_tab = kwargs.get(
'start_browser_tab', 
False)
    97                     if (name 
is None) 
and (
'fireflyChannelLab' in os.environ):
    98                         name = os.environ[
'fireflyChannelLab']
    99                 elif 'FIREFLY_URL' in os.environ:
   100                     url = os.environ[
'FIREFLY_URL']
   102                     raise RuntimeError(
'Cannot determine url from environment; you must pass url')
   106                         print(
'Starting Jupyterlab client')
   107                     _fireflyClient = firefly_client.FireflyClient.make_lab_client(
   108                         start_tab=
True, start_browser_tab=start_browser_tab,
   109                         html_file=kwargs.get(
'html_file'), verbose=verbose)
   112                         print(
'Starting vanilla client')
   113                     _fireflyClient = firefly_client.FireflyClient.make_client(
   114                         url=url, html_file=html_file, launch_browser=
True,
   115                         channel_override=name, verbose=verbose)
   116             except (HandshakeError, gaierror) 
as e:
   117                 raise RuntimeError(
"Unable to connect to %s: %s" % (url 
or '', e))
   121             except Exception 
as e:
   122                 raise RuntimeError(
"Cannot add listener. Browser must be connected" +
   124                                    (_fireflyClient.get_firefly_url(), e))
   132         self.
_channel = _fireflyClient.channel
   133         self.
_url = _fireflyClient.get_firefly_url()
   142     def _getRegionLayerId(self):
   143         return "lsstRegions%s" % self.display.frame 
if self.display 
else "None"   145     def _clearImage(self):
   146         """Delete the current image in the Firefly viewer   148         self.
_client.dispatch(action_type=
'ImagePlotCntlr.deletePlotView',
   149                               payload=dict(plotId=
str(self.display.frame)))
   151     def _mtv(self, image, mask=None, wcs=None, title=""):
   152         """Display an Image and/or Mask on a Firefly display   155             title = 
str(self.display.frame)
   158                 print(
'displaying image')
   161             with tempfile.NamedTemporaryFile() 
as fd:
   162                 displayLib.writeFitsImage(fd.name, image, wcs, title)
   167             extraParams = dict(Title=title,
   169                                PredefinedOverlayIds=
' ',
   170                                viewer_id=
'image-' + 
str(self.frame))
   175                 extraParams[
'InitZoomLevel'] = self.
_lastZoom   176                 extraParams[
'ZoomType'] = 
'LEVEL'   178                 extraParams[
'InitialCenterPosition'] = 
'{0:.3f};{1:.3f};PIXEL'.
format(
   183             ret = _fireflyClient.show_fits(self.
_fireflyFitsID, plot_id=
str(self.display.frame),
   186             if not ret[
"success"]:
   187                 raise RuntimeError(
"Display of image failed")
   191                 print(
'displaying mask')
   192             with tempfile.NamedTemporaryFile() 
as fdm:
   193                 displayLib.writeFitsImage(fdm.name, mask, wcs, title)
   198             maskPlaneDict = mask.getMaskPlaneDict()
   199             for k, v 
in maskPlaneDict.items():
   204                 if (((1 << self.
_maskDict[k]) & usedPlanes) 
and   208                     _fireflyClient.add_mask(bit_number=self.
_maskDict[k],
   210                                             plot_id=
str(self.display.frame),
   219     def _remove_masks(self):
   220         """Remove mask layers"""   222             _fireflyClient.remove_mask(plot_id=
str(self.display.frame), mask_id=k)
   225     def _buffer(self, enable=True):
   226         """!Enable or disable buffering of writes to the display   227         param enable  True or False, as appropriate   232         """!Flush any I/O buffers   238             print(
"Flushing %d regions" % len(self.
_regions))
   242         _fireflyClient.add_region_data(region_data=self.
_regions, plot_id=
str(self.display.frame),
   246     def _uploadTextData(self, regions):
   253         """Called when the device is closed"""   255             print(
"Closing firefly device %s" % (self.display.frame 
if self.display 
else "[None]"))
   256         if _fireflyClient 
is not None:
   257             _fireflyClient.disconnect()
   258             _fireflyClient.session.close()
   260     def _dot(self, symb, c, r, size, ctype, fontFamily="helvetica", textAngle=None):
   261         """Draw a symbol onto the specified DS9 frame at (col,row) = (c,r) [0-based coordinates]   267             @:Mxx,Mxy,Myy    Draw an ellipse with moments (Mxx, Mxy, Myy) (argument size is ignored)   268             An object derived from afwGeom.ellipses.BaseCore Draw the ellipse (argument size is ignored)   269     Any other value is interpreted as a string to be drawn. Strings obey the fontFamily (which may be extended   270     with other characteristics, e.g. "times bold italic".  Text will be drawn rotated by textAngle (textAngle   271     is ignored otherwise).   273     N.b. objects derived from BaseCore include Axes and Quadrupole.   275         self.
_uploadTextData(ds9Regions.dot(symb, c, r, size, ctype, fontFamily, textAngle))
   277     def _drawLines(self, points, ctype):
   278         """Connect the points, a list of (col,row)   279         Ctype is the name of a colour (e.g. 'red')"""   284         """Erase all overlays on the image"""   288             _fireflyClient.delete_region_layer(self.
_regionLayerId, plot_id=
str(self.display.frame))
   290     def _setCallback(self, what, func):
   291         if func != interface.noop_callback:
   293                 status = _fireflyClient.add_extension(
'POINT' if False else 'AREA_SELECT', title=what,
   294                                                       plot_id=
str(self.display.frame),
   296                 if not status[
'success']:
   298             except Exception 
as e:
   299                 raise RuntimeError(
"Cannot set callback. Browser must be (re)opened " +
   301                                    (_fireflyClient.url_bw,
   302                                     _fireflyClient.channel, e))
   305         """Return an event generated by a keypress or mouse click   307         ev = interface.Event(
"q")
   310             print(
"virtual[%s]._getEvent() -> %s" % (self.display.frame, ev))
   317     def _scale(self, algorithm, min, max, unit=None, *args, **kwargs):
   318         """Scale the image stretch and limits   323             stretch algorithm, e.g. 'linear', 'log', 'loglog', 'equal', 'squared',   324             'sqrt', 'asinh', powerlaw_gamma'   325         min : `float` or `str`   326             lower limit, or 'minmax' for full range, or 'zscale'   327         max : `float` or `str`   328             upper limit; overrriden if min is 'minmax' or 'zscale'   330             unit for min and max. 'percent', 'absolute', 'sigma'.   331             if not specified, min and max are presumed to be in 'absolute' units.   333         *args, **kwargs : additional position and keyword arguments.   334             The options are shown below:   336             **Q** : `float`, optional   337                 The asinh softening parameter for asinh stretch.   338                 Use Q=0 for linear stretch, increase Q to make brighter features visible.   339                 When not specified or None, Q is calculated by Firefly to use full color range.   341                 The gamma value for power law gamma stretch (default 2.0)   342             **zscale_contrast** : `int`, optional   343                 Contrast parameter in percent for zscale algorithm (default 25)   344             **zscale_samples** : `int`, optional   345                 Number of samples for zscale algorithm (default 600)   346             **zscale_samples_perline** : `int`, optional   347                 Number of samples per line for zscale algorithm (default 120)   349         stretch_algorithms = (
'linear', 
'log', 
'loglog', 
'equal', 
'squared', 
'sqrt',
   350                               'asinh', 
'powerlaw_gamma')
   351         interval_methods = (
'percent', 
'maxmin', 
'absolute', 
'zscale', 
'sigma')
   357             algorithm = dict((a.lower(), a) 
for a 
in stretch_algorithms).get(algorithm.lower(), algorithm)
   359             if algorithm 
not in stretch_algorithms:
   360                 raise FireflyError(
'Algorithm %s is invalid; please choose one of "%s"' %
   361                                    (algorithm, 
'", "'.join(stretch_algorithms)))
   368             kwargs[
'asinh_q_value'] = kwargs[
'Q']
   371         if 'gamma' in kwargs:
   372             kwargs[
'gamma_value'] = kwargs[
'gamma']
   376             interval_type = 
'percent'   379         elif min == 
'zscale':
   380             interval_type = 
'zscale'   387         units = (
'percent', 
'absolute', 
'sigma')
   388         if unit 
not in units:
   389             raise FireflyError(
'Unit %s is invalid; please choose one of "%s"' % (unit, 
'", "'.join(units)))
   392             interval_type = 
'sigma'   393         elif unit == 
'absolute' and interval_type 
is None:
   394             interval_type = 
'absolute'   395         elif unit == 
'percent':
   396             interval_type = 
'percent'   402         if interval_type 
not in interval_methods:
   403             raise FireflyError(
'Interval method %s is invalid' % interval_type)
   406         if interval_type != 
'zscale':
   407             rval = _fireflyClient.set_stretch(
str(self.display.frame), stype=interval_type,
   408                                               algorithm=algorithm, lower_value=min,
   409                                               upper_value=max, **kwargs)
   411             if 'zscale_contrast' not in kwargs:
   412                 kwargs[
'zscale_contrast'] = 25
   413             if 'zscale_samples' not in kwargs:
   414                 kwargs[
'zscale_samples'] = 600
   415             if 'zscale_samples_perline' not in kwargs:
   416                 kwargs[
'zscale_samples_perline'] = 120
   417             rval = _fireflyClient.set_stretch(
str(self.display.frame), stype=
'zscale',
   418                                               algorithm=algorithm, **kwargs)
   420         if 'rv_string' in rval:
   423     def _setMaskTransparency(self, transparency, maskName):
   424         """Specify mask transparency (percent); or None to not set it when loading masks"""   425         if maskName 
is not None:
   426             masklist = [maskName]
   428             masklist = 
set(self.
_maskIds + 
list(self.display._defaultMaskPlaneColor.keys()))
   431             _fireflyClient.dispatch(action_type=
'ImagePlotCntlr.overlayPlotChangeAttributes',
   432                                     payload={
'plotId': 
str(self.display.frame),
   434                                              'attributes': {
'opacity': 1.0 - transparency/100.},
   437     def _getMaskTransparency(self, maskName):
   438         """Return the current mask's transparency"""   444     def _setMaskPlaneColor(self, maskName, color):
   445         """Specify mask color """   446         _fireflyClient.remove_mask(plot_id=
str(self.display.frame),
   449         if (color.lower() != 
'ignore'):
   450             _fireflyClient.add_mask(bit_number=self.
_maskDict[maskName],
   452                                     plot_id=
str(self.display.frame),
   458         """Show the requested window"""   459         if self.
_client.render_tree_id 
is not None:
   464             localbrowser, url = _fireflyClient.launch_browser(verbose=self.verbose)
   465             if not localbrowser 
and not self.verbose:
   466                 _fireflyClient.display_url()
   472     def _zoom(self, zoomfac):
   473         """Zoom display by specified amount   478             zoom level in screen pixels per image pixel   481         _fireflyClient.set_zoom(plot_id=
str(self.display.frame), factor=zoomfac)
   483     def _pan(self, colc, rowc):
   484         """Pan to specified pixel coordinates   489             column and row in units of pixels (zero-based convention,   490               with the xy0 already subtracted off)   492         self.
_lastPan = [colc+0.5, rowc+0.5]  
   494         _fireflyClient.set_pan(plot_id=
str(self.display.frame), x=colc, y=rowc)
   499         """Get the instance of FireflyClient for this display   503         `firefly_client.FireflyClient`   504             Instance of FireflyClient used by this display   509         """Reinitialize the viewer   514         """Reset the layout of the Firefly Slate browser   516         Clears the display and adds Slate cells to display image in upper left,   517         plot area in upper right, and plots stretch across the bottom   520         self.
_client.add_cell(row=2, col=0, width=4, height=2, element_type=
'tables',
   522         self.
_client.add_cell(row=0, col=0, width=2, height=3, element_type=
'images',
   523                               cell_id=
'image-%s' % 
str(self.display.frame))
   524         self.
_client.add_cell(row=0, col=2, width=2, height=3, element_type=
'xyPlots',
   528                           highlightColor='cyan', selectColor=
'orange',
   529                           style=
'fill', layerString=
'detection footprints ',
   530                           titleString=
'catalog footprints '):
   531         """Overlay outlines of footprints from a catalog   533         Overlay outlines of LSST footprints from the input catalog. The colors   534         and style can be specified as parameters, and the base color and style   535         can be changed in the Firefly browser user interface.   539         catalog : `lsst.afw.table.SourceCatalog`   540             Source catalog from which to display footprints.   542             Color for footprints overlay. Colors can be specified as a name   543             like 'cyan' or afwDisplay.RED; as an rgb value such as   544             'rgb(80,100,220)'; or as rgb plus alpha (transparency) such   545             as 'rgba('74,144,226,0.60)'.   546         highlightColor : `str`   547             Color for highlighted footprints   549             Color for selected footprints   550         style : {'fill', 'outline'}   551             Style of footprints display, filled or outline   553             Column at which to insert the "family_id" and "category" columns   555             Name of footprints layer string, to concatenate with the frame   556             Re-using the layer_string will overwrite the previous table and   559             Title of catalog, to concatenate with the frame   562         with BytesIO() 
as fd:
   563             footprintTable.to_xml(fd)
   564             tableval = self.
_client.upload_data(fd, 
'UNKNOWN')
   565         self.
_client.overlay_footprints(footprint_file=tableval,
   566                                         title=titleString + 
str(self.display.frame),
   567                                         footprint_layer_id=layerString + 
str(self.display.frame),
   568                                         plot_id=
str(self.display.frame),
   570                                         highlightColor=highlightColor,
   571                                         selectColor=selectColor,
 
def _setMaskTransparency(self, transparency, maskName)
def __handleCallbacks(event)
std::shared_ptr< FrameSet > append(FrameSet const &first, FrameSet const &second)
Construct a FrameSet that performs two transformations in series. 
daf::base::PropertySet * set
Statistics makeStatistics(lsst::afw::math::MaskedVector< EntryT > const &mv, std::vector< WeightPixel > const &vweights, int const flags, StatisticsControl const &sctrl=StatisticsControl())
The makeStatistics() overload to handle lsst::afw::math::MaskedVector<> 
def _flush(self)
Flush any I/O buffers. 
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)
def overlayFootprints(self, catalog, color='rgba(74, 144, 226, 0.60)', highlightColor='cyan', selectColor='orange', style='fill', layerString='detection footprints ', titleString='catalog footprints ')
def _uploadTextData(self, regions)
def getMaskPlaneColor(name, frame=None)
def _getRegionLayerId(self)
def __init__(self, display, verbose=False, url=None, name=None, args, kwargs)
daf::base::PropertyList * list