LSSTApplications  17.0+124,17.0+14,17.0+73,18.0.0+37,18.0.0+80,18.0.0-4-g68ffd23+4,18.1.0-1-g0001055+12,18.1.0-1-g03d53ef+5,18.1.0-1-g1349e88+55,18.1.0-1-g2505f39+44,18.1.0-1-g5315e5e+4,18.1.0-1-g5e4b7ea+14,18.1.0-1-g7e8fceb+4,18.1.0-1-g85f8cd4+48,18.1.0-1-g8ff0b9f+4,18.1.0-1-ga2c679d+1,18.1.0-1-gd55f500+35,18.1.0-10-gb58edde+2,18.1.0-11-g0997b02+4,18.1.0-13-gfe4edf0b+12,18.1.0-14-g259bd21+21,18.1.0-19-gdb69f3f+2,18.1.0-2-g5f9922c+24,18.1.0-2-gd3b74e5+11,18.1.0-2-gfbf3545+32,18.1.0-26-g728bddb4+5,18.1.0-27-g6ff7ca9+2,18.1.0-3-g52aa583+25,18.1.0-3-g8ea57af+9,18.1.0-3-gb69f684+42,18.1.0-3-gfcaddf3+6,18.1.0-32-gd8786685a,18.1.0-4-gf3f9b77+6,18.1.0-5-g1dd662b+2,18.1.0-5-g6dbcb01+41,18.1.0-6-gae77429+3,18.1.0-7-g9d75d83+9,18.1.0-7-gae09a6d+30,18.1.0-9-gc381ef5+4,w.2019.45
LSSTDataManagementBasePackage
firefly.py
Go to the documentation of this file.
1 #
2 # LSST Data Management System
3 # Copyright 2008, 2009, 2010, 2015 LSST Corporation.
4 #
5 # This product includes software developed by the
6 # LSST Project (http://www.lsst.org/).
7 #
8 # This program is free software: you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation, either version 3 of the License, or
11 # (at your option) any later version.
12 #
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
17 #
18 # You should have received a copy of the LSST License Statement and
19 # the GNU General Public License along with this program. If not,
20 # see <http://www.lsstcorp.org/LegalNotices/>.
21 #
22 
23 from __future__ import absolute_import, division, print_function
24 from past.builtins import long
25 
26 from io import BytesIO
27 from socket import gaierror
28 import tempfile
29 
30 import lsst.afw.display.interface as interface
31 import lsst.afw.display.virtualDevice as virtualDevice
32 import lsst.afw.display.ds9Regions as ds9Regions
33 import lsst.afw.display.displayLib as displayLib
34 import lsst.afw.math as afwMath
35 import lsst.log
36 
37 from .footprints import createFootprintsTable
38 
39 try:
40  import firefly_client
41  _fireflyClient = None
42 except ImportError as e:
43  raise RuntimeError("Cannot import firefly_client: %s" % (e))
44 from ws4py.client import HandshakeError
45 
46 
47 class FireflyError(Exception):
48 
49  def __init__(self, str):
50  Exception.__init__(self, str)
51 
52 
54  """Return the version of firefly_client in use, as a string"""
55  return(firefly_client.__version__)
56 
57 
58 class DisplayImpl(virtualDevice.DisplayImpl):
59  """Device to talk to a firefly display"""
60 
61  @staticmethod
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',
67  'ColorTable': '9'}
68  plot_id = 3
69  global _fireflyClient
70  _fireflyClient.show_fits(fileOnServer=None, plot_id=plot_id, additionalParams=pParams)
71 
72  lsst.log.debug("Callback event info: {}".format(event))
73  return
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'))
77 
78  def __init__(self, display, verbose=False, url=None,
79  name=None, *args, **kwargs):
80  virtualDevice.DisplayImpl.__init__(self, display, verbose)
81 
82  if self.verbose:
83  print("Opening firefly device %s" % (self.display.frame if self.display else "[None]"))
84 
85  global _fireflyClient
86  if not _fireflyClient:
87  import os
88  start_tab = None
89  html_file = kwargs.get('html_file',
90  os.environ.get('FIREFLY_HTML', 'slate.html'))
91  if url is None:
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']
101  else:
102  raise RuntimeError('Cannot determine url from environment; you must pass url')
103 
104  token = kwargs.get('token',
105  os.environ.get('ACCESS_TOKEN', None))
106 
107  try:
108  if start_tab:
109  if verbose:
110  print('Starting Jupyterlab client')
111  _fireflyClient = firefly_client.FireflyClient.make_lab_client(
112  start_tab=True, start_browser_tab=start_browser_tab,
113  html_file=kwargs.get('html_file'), verbose=verbose,
114  token=token)
115 
116  else:
117  if verbose:
118  print('Starting vanilla client')
119  _fireflyClient = firefly_client.FireflyClient.make_client(
120  url=url, html_file=html_file, launch_browser=True,
121  channel_override=name, verbose=verbose,
122  token=token)
123 
124  except (HandshakeError, gaierror) as e:
125  raise RuntimeError("Unable to connect to %s: %s" % (url or '', e))
126 
127  try:
128  _fireflyClient.add_listener(self.__handleCallbacks)
129  except Exception as e:
130  raise RuntimeError("Cannot add listener. Browser must be connected" +
131  "to %s: %s" %
132  (_fireflyClient.get_firefly_url(), e))
133 
134  self._isBuffered = False
135  self._regions = []
136  self._regionLayerId = self._getRegionLayerId()
137  self._fireflyFitsID = None
138  self._fireflyMaskOnServer = None
139  self._client = _fireflyClient
140  self._channel = _fireflyClient.channel
141  self._url = _fireflyClient.get_firefly_url()
142  self._maskIds = []
143  self._maskDict = {}
144  self._maskPlaneColors = {}
145  self._maskTransparencies = {}
146  self._lastZoom = None
147  self._lastPan = None
148  self._lastStretch = None
149 
150  def _getRegionLayerId(self):
151  return "lsstRegions%s" % self.display.frame if self.display else "None"
152 
153  def _clearImage(self):
154  """Delete the current image in the Firefly viewer
155  """
156  self._client.dispatch(action_type='ImagePlotCntlr.deletePlotView',
157  payload=dict(plotId=str(self.display.frame)))
158 
159  def _mtv(self, image, mask=None, wcs=None, title=""):
160  """Display an Image and/or Mask on a Firefly display
161  """
162  if title == "":
163  title = str(self.display.frame)
164  if image:
165  if self.verbose:
166  print('displaying image')
167  self._erase()
168 
169  with tempfile.NamedTemporaryFile() as fd:
170  displayLib.writeFitsImage(fd.name, image, wcs, title)
171  fd.flush()
172  fd.seek(0, 0)
173  self._fireflyFitsID = _fireflyClient.upload_data(fd, 'FITS')
174 
175  try:
176  viewer_id = ('image-' + str(_fireflyClient.render_tree_id) + '-' +
177  str(self.frame))
178  except AttributeError:
179  viewer_id = 'image-' + str(self.frame)
180  extraParams = dict(Title=title,
181  MultiImageIdx=0,
182  PredefinedOverlayIds=' ',
183  viewer_id=viewer_id)
184  # Firefly's Javascript API requires a space for parameters;
185  # otherwise the parameter will be ignored
186 
187  if self._lastZoom:
188  extraParams['InitZoomLevel'] = self._lastZoom
189  extraParams['ZoomType'] = 'LEVEL'
190  if self._lastPan:
191  extraParams['InitialCenterPosition'] = '{0:.3f};{1:.3f};PIXEL'.format(
192  self._lastPan[0], self._lastPan[1])
193  if self._lastStretch:
194  extraParams['RangeValues'] = self._lastStretch
195 
196  ret = _fireflyClient.show_fits(self._fireflyFitsID, plot_id=str(self.display.frame),
197  **extraParams)
198 
199  if not ret["success"]:
200  raise RuntimeError("Display of image failed")
201 
202  if mask:
203  if self.verbose:
204  print('displaying mask')
205  with tempfile.NamedTemporaryFile() as fdm:
206  displayLib.writeFitsImage(fdm.name, mask, wcs, title)
207  fdm.flush()
208  fdm.seek(0, 0)
209  self._fireflyMaskOnServer = _fireflyClient.upload_data(fdm, 'FITS')
210 
211  maskPlaneDict = mask.getMaskPlaneDict()
212  for k, v in maskPlaneDict.items():
213  self._maskDict[k] = v
214  self._maskPlaneColors[k] = self.display.getMaskPlaneColor(k)
215  usedPlanes = long(afwMath.makeStatistics(mask, afwMath.SUM).getValue())
216  for k in self._maskDict:
217  if (((1 << self._maskDict[k]) & usedPlanes) and
218  (k in self._maskPlaneColors) and
219  (self._maskPlaneColors[k] is not None) and
220  (self._maskPlaneColors[k].lower() != 'ignore')):
221  _fireflyClient.add_mask(bit_number=self._maskDict[k],
222  image_number=0,
223  plot_id=str(self.display.frame),
224  mask_id=k,
225  title=k + ' - bit %d'%self._maskDict[k],
226  color=self._maskPlaneColors[k],
227  file_on_server=self._fireflyMaskOnServer)
228  if k in self._maskTransparencies:
230  self._maskIds.append(k)
231 
232  def _remove_masks(self):
233  """Remove mask layers"""
234  for k in self._maskIds:
235  _fireflyClient.remove_mask(plot_id=str(self.display.frame), mask_id=k)
236  self._maskIds = []
237 
238  def _buffer(self, enable=True):
239  """!Enable or disable buffering of writes to the display
240  param enable True or False, as appropriate
241  """
242  self._isBuffered = enable
243 
244  def _flush(self):
245  """!Flush any I/O buffers
246  """
247  if not self._regions:
248  return
249 
250  if self.verbose:
251  print("Flushing %d regions" % len(self._regions))
252  print(self._regions)
253 
254  self._regionLayerId = self._getRegionLayerId()
255  _fireflyClient.add_region_data(region_data=self._regions, plot_id=str(self.display.frame),
256  region_layer_id=self._regionLayerId)
257  self._regions = []
258 
259  def _uploadTextData(self, regions):
260  self._regions += regions
261 
262  if not self._isBuffered:
263  self._flush()
264 
265  def _close(self):
266  """Called when the device is closed"""
267  if self.verbose:
268  print("Closing firefly device %s" % (self.display.frame if self.display else "[None]"))
269  if _fireflyClient is not None:
270  _fireflyClient.disconnect()
271  _fireflyClient.session.close()
272 
273  def _dot(self, symb, c, r, size, ctype, fontFamily="helvetica", textAngle=None):
274  """Draw a symbol onto the specified DS9 frame at (col,row) = (c,r) [0-based coordinates]
275  Possible values are:
276  + Draw a +
277  x Draw an x
278  * Draw a *
279  o Draw a circle
280  @:Mxx,Mxy,Myy Draw an ellipse with moments (Mxx, Mxy, Myy) (argument size is ignored)
281  An object derived from afwGeom.ellipses.BaseCore Draw the ellipse (argument size is ignored)
282  Any other value is interpreted as a string to be drawn. Strings obey the fontFamily (which may be extended
283  with other characteristics, e.g. "times bold italic". Text will be drawn rotated by textAngle (textAngle
284  is ignored otherwise).
285 
286  N.b. objects derived from BaseCore include Axes and Quadrupole.
287  """
288  self._uploadTextData(ds9Regions.dot(symb, c, r, size, ctype, fontFamily, textAngle))
289 
290  def _drawLines(self, points, ctype):
291  """Connect the points, a list of (col,row)
292  Ctype is the name of a colour (e.g. 'red')"""
293 
294  self._uploadTextData(ds9Regions.drawLines(points, ctype))
295 
296  def _erase(self):
297  """Erase all overlays on the image"""
298  if self.verbose:
299  print('region layer id is {}'.format(self._regionLayerId))
300  if self._regionLayerId:
301  _fireflyClient.delete_region_layer(self._regionLayerId, plot_id=str(self.display.frame))
302 
303  def _setCallback(self, what, func):
304  if func != interface.noop_callback:
305  try:
306  status = _fireflyClient.add_extension('POINT' if False else 'AREA_SELECT', title=what,
307  plot_id=str(self.display.frame),
308  extension_id=what)
309  if not status['success']:
310  pass
311  except Exception as e:
312  raise RuntimeError("Cannot set callback. Browser must be (re)opened " +
313  "to %s%s : %s" %
314  (_fireflyClient.url_bw,
315  _fireflyClient.channel, e))
316 
317  def _getEvent(self):
318  """Return an event generated by a keypress or mouse click
319  """
320  ev = interface.Event("q")
321 
322  if self.verbose:
323  print("virtual[%s]._getEvent() -> %s" % (self.display.frame, ev))
324 
325  return ev
326  #
327  # Set gray scale
328  #
329 
330  def _scale(self, algorithm, min, max, unit=None, *args, **kwargs):
331  """Scale the image stretch and limits
332 
333  Parameters:
334  -----------
335  algorithm : `str`
336  stretch algorithm, e.g. 'linear', 'log', 'loglog', 'equal', 'squared',
337  'sqrt', 'asinh', powerlaw_gamma'
338  min : `float` or `str`
339  lower limit, or 'minmax' for full range, or 'zscale'
340  max : `float` or `str`
341  upper limit; overrriden if min is 'minmax' or 'zscale'
342  unit : `str`
343  unit for min and max. 'percent', 'absolute', 'sigma'.
344  if not specified, min and max are presumed to be in 'absolute' units.
345 
346  *args, **kwargs : additional position and keyword arguments.
347  The options are shown below:
348 
349  **Q** : `float`, optional
350  The asinh softening parameter for asinh stretch.
351  Use Q=0 for linear stretch, increase Q to make brighter features visible.
352  When not specified or None, Q is calculated by Firefly to use full color range.
353  **gamma**
354  The gamma value for power law gamma stretch (default 2.0)
355  **zscale_contrast** : `int`, optional
356  Contrast parameter in percent for zscale algorithm (default 25)
357  **zscale_samples** : `int`, optional
358  Number of samples for zscale algorithm (default 600)
359  **zscale_samples_perline** : `int`, optional
360  Number of samples per line for zscale algorithm (default 120)
361  """
362  stretch_algorithms = ('linear', 'log', 'loglog', 'equal', 'squared', 'sqrt',
363  'asinh', 'powerlaw_gamma')
364  interval_methods = ('percent', 'maxmin', 'absolute', 'zscale', 'sigma')
365  #
366  #
367  # Normalise algorithm's case
368  #
369  if algorithm:
370  algorithm = dict((a.lower(), a) for a in stretch_algorithms).get(algorithm.lower(), algorithm)
371 
372  if algorithm not in stretch_algorithms:
373  raise FireflyError('Algorithm %s is invalid; please choose one of "%s"' %
374  (algorithm, '", "'.join(stretch_algorithms)))
375  self._stretchAlgorithm = algorithm
376  else:
377  algorithm = 'linear'
378 
379  # Translate parameters for asinh and powerlaw_gamma stretches
380  if 'Q' in kwargs:
381  kwargs['asinh_q_value'] = kwargs['Q']
382  del kwargs['Q']
383 
384  if 'gamma' in kwargs:
385  kwargs['gamma_value'] = kwargs['gamma']
386  del kwargs['gamma']
387 
388  if min == 'minmax':
389  interval_type = 'percent'
390  unit = 'percent'
391  min, max = 0, 100
392  elif min == 'zscale':
393  interval_type = 'zscale'
394  else:
395  interval_type = None
396 
397  if not unit:
398  unit = 'absolute'
399 
400  units = ('percent', 'absolute', 'sigma')
401  if unit not in units:
402  raise FireflyError('Unit %s is invalid; please choose one of "%s"' % (unit, '", "'.join(units)))
403 
404  if unit == 'sigma':
405  interval_type = 'sigma'
406  elif unit == 'absolute' and interval_type is None:
407  interval_type = 'absolute'
408  elif unit == 'percent':
409  interval_type = 'percent'
410 
411  self._stretchMin = min
412  self._stretchMax = max
413  self._stretchUnit = unit
414 
415  if interval_type not in interval_methods:
416  raise FireflyError('Interval method %s is invalid' % interval_type)
417 
418  rval = {}
419  if interval_type != 'zscale':
420  rval = _fireflyClient.set_stretch(str(self.display.frame), stype=interval_type,
421  algorithm=algorithm, lower_value=min,
422  upper_value=max, **kwargs)
423  else:
424  if 'zscale_contrast' not in kwargs:
425  kwargs['zscale_contrast'] = 25
426  if 'zscale_samples' not in kwargs:
427  kwargs['zscale_samples'] = 600
428  if 'zscale_samples_perline' not in kwargs:
429  kwargs['zscale_samples_perline'] = 120
430  rval = _fireflyClient.set_stretch(str(self.display.frame), stype='zscale',
431  algorithm=algorithm, **kwargs)
432 
433  if 'rv_string' in rval:
434  self._lastStretch = rval['rv_string']
435 
436  def _setMaskTransparency(self, transparency, maskName):
437  """Specify mask transparency (percent); or None to not set it when loading masks"""
438  if maskName is not None:
439  masklist = [maskName]
440  else:
441  masklist = set(self._maskIds + list(self.display._defaultMaskPlaneColor.keys()))
442  for k in masklist:
443  self._maskTransparencies[k] = transparency
444  _fireflyClient.dispatch(action_type='ImagePlotCntlr.overlayPlotChangeAttributes',
445  payload={'plotId': str(self.display.frame),
446  'imageOverlayId': k,
447  'attributes': {'opacity': 1.0 - transparency/100.},
448  'doReplot': False})
449 
450  def _getMaskTransparency(self, maskName):
451  """Return the current mask's transparency"""
452  transparency = None
453  if maskName in self._maskTransparencies:
454  transparency = self._maskTransparencies[maskName]
455  return transparency
456 
457  def _setMaskPlaneColor(self, maskName, color):
458  """Specify mask color """
459  _fireflyClient.remove_mask(plot_id=str(self.display.frame),
460  mask_id=maskName)
461  self._maskPlaneColors[maskName] = color
462  if (color.lower() != 'ignore'):
463  _fireflyClient.add_mask(bit_number=self._maskDict[maskName],
464  image_number=1,
465  plot_id=str(self.display.frame),
466  mask_id=maskName,
467  color=self.display.getMaskPlaneColor(maskName),
468  file_on_server=self._fireflyFitsID)
469 
470  def _show(self):
471  """Show the requested window"""
472  if self._client.render_tree_id is not None:
473  # we are using Jupyterlab
474  self._client.dispatch(self._client.ACTION_DICT['StartLabWindow'],
475  {})
476  else:
477  localbrowser, url = _fireflyClient.launch_browser(verbose=self.verbose)
478  if not localbrowser and not self.verbose:
479  _fireflyClient.display_url()
480 
481  #
482  # Zoom and Pan
483  #
484 
485  def _zoom(self, zoomfac):
486  """Zoom display by specified amount
487 
488  Parameters:
489  -----------
490  zoomfac: `float`
491  zoom level in screen pixels per image pixel
492  """
493  self._lastZoom = zoomfac
494  _fireflyClient.set_zoom(plot_id=str(self.display.frame), factor=zoomfac)
495 
496  def _pan(self, colc, rowc):
497  """Pan to specified pixel coordinates
498 
499  Parameters:
500  -----------
501  colc, rowc : `float`
502  column and row in units of pixels (zero-based convention,
503  with the xy0 already subtracted off)
504  """
505  self._lastPan = [colc+0.5, rowc+0.5] # saved for future use in _mtv
506  # Firefly's internal convention is first pixel is (0.5, 0.5)
507  _fireflyClient.set_pan(plot_id=str(self.display.frame), x=colc, y=rowc)
508 
509  # Extensions to the API that are specific to using the Firefly backend
510 
511  def getClient(self):
512  """Get the instance of FireflyClient for this display
513 
514  Returns:
515  --------
516  `firefly_client.FireflyClient`
517  Instance of FireflyClient used by this display
518  """
519  return self._client
520 
521  def clearViewer(self):
522  """Reinitialize the viewer
523  """
524  self._client.reinit_viewer()
525 
526  def resetLayout(self):
527  """Reset the layout of the Firefly Slate browser
528 
529  Clears the display and adds Slate cells to display image in upper left,
530  plot area in upper right, and plots stretch across the bottom
531  """
532  self.clearViewer()
533  try:
534  tables_cell_id = 'tables-' + str(_fireflyClient.render_tree_id)
535  except AttributeError:
536  tables_cell_id = 'tables'
537  self._client.add_cell(row=2, col=0, width=4, height=2, element_type='tables',
538  cell_id=tables_cell_id)
539  try:
540  image_cell_id = ('image-' + str(_fireflyClient.render_tree_id) + '-' +
541  str(self.frame))
542  except AttributeError:
543  image_cell_id = 'image-' + str(self.frame)
544  self._client.add_cell(row=0, col=0, width=2, height=3, element_type='images',
545  cell_id=image_cell_id)
546  try:
547  plots_cell_id = 'plots-' + str(_fireflyClient.render_tree_id)
548  except AttributeError:
549  plots_cell_id = 'plots'
550  self._client.add_cell(row=0, col=2, width=2, height=3, element_type='xyPlots',
551  cell_id=plots_cell_id)
552 
553  def overlayFootprints(self, catalog, color='rgba(74,144,226,0.60)',
554  highlightColor='cyan', selectColor='orange',
555  style='fill', layerString='detection footprints ',
556  titleString='catalog footprints '):
557  """Overlay outlines of footprints from a catalog
558 
559  Overlay outlines of LSST footprints from the input catalog. The colors
560  and style can be specified as parameters, and the base color and style
561  can be changed in the Firefly browser user interface.
562 
563  Parameters:
564  -----------
565  catalog : `lsst.afw.table.SourceCatalog`
566  Source catalog from which to display footprints.
567  color : `str`
568  Color for footprints overlay. Colors can be specified as a name
569  like 'cyan' or afwDisplay.RED; as an rgb value such as
570  'rgb(80,100,220)'; or as rgb plus alpha (transparency) such
571  as 'rgba('74,144,226,0.60)'.
572  highlightColor : `str`
573  Color for highlighted footprints
574  selectColor : `str`
575  Color for selected footprints
576  style : {'fill', 'outline'}
577  Style of footprints display, filled or outline
578  insertColumn : `int`
579  Column at which to insert the "family_id" and "category" columns
580  layerString: `str`
581  Name of footprints layer string, to concatenate with the frame
582  Re-using the layer_string will overwrite the previous table and
583  footprints
584  titleString: `str`
585  Title of catalog, to concatenate with the frame
586  """
587  footprintTable = createFootprintsTable(catalog)
588  with BytesIO() as fd:
589  footprintTable.to_xml(fd)
590  tableval = self._client.upload_data(fd, 'UNKNOWN')
591  self._client.overlay_footprints(footprint_file=tableval,
592  title=titleString + str(self.display.frame),
593  footprint_layer_id=layerString + str(self.display.frame),
594  plot_id=str(self.display.frame),
595  color=color,
596  highlightColor=highlightColor,
597  selectColor=selectColor,
598  style=style)
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)
Definition: history.py:174
def _setMaskTransparency(self, transparency, maskName)
Definition: firefly.py:436
std::shared_ptr< FrameSet > append(FrameSet const &first, FrameSet const &second)
Construct a FrameSet that performs two transformations in series.
Definition: functional.cc:33
daf::base::PropertySet * set
Definition: fits.cc:902
Definition: Log.h:706
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<>
Definition: Statistics.h:520
def _flush(self)
Flush any I/O buffers.
Definition: firefly.py:244
def overlayFootprints(self, catalog, color='rgba(74, 144, 226, 0.60)', highlightColor='cyan', selectColor='orange', style='fill', layerString='detection footprints ', titleString='catalog footprints ')
Definition: firefly.py:556
def getMaskPlaneColor(name, frame=None)
Definition: ds9.py:77
def __init__(self, display, verbose=False, url=None, name=None, args, kwargs)
Definition: firefly.py:79
def createFootprintsTable(catalog, xy0=None, insertColumn=4)
Definition: footprints.py:62
daf::base::PropertyList * list
Definition: fits.cc:903