22__all__ = [
"AstroWidgetsVersion",
"DisplayImpl"]
25from astropy.table
import Table
33 from ginga.misc.log
import get_logger
34 from ginga.AstroImage
import AstroImage
35 from ginga.util.wcsmod.wcs_astropy
import AstropyWCS
39 logging.getLogger(
"lsst.afw.display.astrowidgets").warning(
"Cannot import ginga libraries.")
53 haveAstrowidgets =
True
55 haveAstrowidgets =
False
60 _maskTransparency =
None
64 """Get the version of DS9 in use.
69 Version of DS9 in use.
71 return astrowidgets.__version__
75 """An event generated by a mouse or key click on the display"""
78 interface.Event.__init__(self, k, x, y)
82 """Virtual device display implementation.
87 Display object to connect to.
88 dims : `tuple` [`int`, `int`], optional
89 Dimensions of the viewer window.
90 use_opencv : `bool`, optional
91 Should openCV be used to speed drawing?
92 verbose : `bool`, optional
93 Increase log verbosity?
95 markerDict = {'+':
'plus',
'x':
'cross',
'.':
'circle',
'*':
'circle',
'o':
'circle'}
97 def __init__(self, display, dims=None, use_opencv=False, verbose=False, *args, **kwargs):
98 virtualDevice.DisplayImpl.__init__(self, display, verbose)
100 width, height = 1024, 768
104 self.
logger = get_logger(
"ginga", log_stderr=
True, level=40)
107 self.
_viewer = astrowidgets.ImageWidget(image_width=width, image_height=height,
108 use_opencv=use_opencv, logger=self.
logger)
118 self.
_canvas.enable_draw(
False)
123 """Attach this display to the output of the current cell."""
127 """Return the ginga viewer"""
131 """Show (or hide) the colour bar.
135 show : `bool`, optional
136 Should the color bar be shown?
141 """Show (or hide) the pan mark.
145 show : `bool`, optional
146 Should the pan marker be shown?
147 color : `str`, optional
148 What color should the pan mark be?
153 """Specify mask transparency (percent); or None to not set it when loading masks.
157 transparency : `float`
158 Transparency of the masks in percent (0-100).
159 maskplane : `str`, optional
160 Unsupported option to only change the transparency of
163 if maskplane
is not None:
164 print(
"display_astrowidgets is not yet able to set transparency for individual maskplanes" % maskplane,
171 """Return the current mask transparency."""
174 def _mtv(self, image, mask=None, wcs=None, title=""):
175 """Display an Image and/or Mask on a ginga display
182 Mask to use,
if the input does
not contain one.
183 wcs : `ginga.util.wcsmod.wcs_astropy`
184 WCS to use,
if the input does
not contain one.
185 title : `str`, optional
186 Unsupported display title.
189 self._canvas.delete_all_objects()
192 Aimage = AstroImage(inherit_primary_header=
True)
193 Aimage.set_data(image.getArray())
201 _wcs.pixtoradec = Aimage.lsst_wcs.pixtoradec
202 _wcs.pixtosystem = Aimage.lsst_wcs.pixtosystem
203 _wcs.radectopix = Aimage.lsst_wcs.radectopix
206 Aimage.wcs.wcs = Aimage.lsst_wcs
209 maskColorFromName = {
'BAD':
'red',
215 'DETECTED_NEGATIVE':
'cyan',
221 for plane, bit
in mask.getMaskPlaneDict().
items():
222 color = maskColorFromName.get(plane,
None)
224 maskDict[1 << bit] = color
232 """Draw mask onto the image display.
238 maskDict : `dict` [`str`, `str`]
239 Dictionary of mask plane names to colors.
241 Transparency to display the mask.
244 from ginga.RGBImage
import RGBImage
245 from ginga
import colors
247 maskArray = maskImage.getArray()
248 height, width = maskArray.shape
249 maskRGBA = np.zeros((height, width, 4), dtype=np.uint8)
250 nSet = np.zeros_like(maskArray, dtype=np.uint8)
252 for maskValue, maskColor
in maskDict.items():
253 r, g, b = colors.lookup_color(maskColor)
254 isSet = (maskArray & maskValue) != 0
255 if (isSet == 0).all():
258 maskRGBA[:, :, 0][isSet] = 255 * r
259 maskRGBA[:, :, 1][isSet] = 255 * g
260 maskRGBA[:, :, 2][isSet] = 255 * b
264 maskRGBA[:, :, 3][nSet == 0] = 0
265 maskRGBA[:, :, 3][nSet != 0] = 255 * maskAlpha
269 maskRGBA[:, :, C] //= nSet
271 rgb_img = RGBImage(data_np=maskRGBA)
272 Image = self.
_viewer.canvas.get_draw_class(
'image')
273 maskImageRGBA = Image(0, 0, rgb_img)
275 if "mask_overlay" in self.
_gingaViewer.canvas.get_tags():
276 self.
_gingaViewer.canvas.delete_object_by_tag(
"mask_overlay")
277 self.
_gingaViewer.canvas.add(maskImageRGBA, tag=
"mask_overlay")
279 def _buffer(self, enable=True):
286 """Erase the display"""
287 self.
_canvas.delete_all_objects()
289 def _dot(self, symb, c, r, size, ctype, fontFamily="helvetica", textAngle=None, label='_dot'):
290 """Draw a symbol at (col,row) = (c,r) [0-based coordinates].
295 Symbol to draw. Should be one of '+',
'x',
'*',
'o',
'.'.
297 Image column
for dot center (0-based coordinates).
299 Image row
for dot center (0-based coordinate).
302 fontFamily : `str`, optional
303 Font to use
for text symbols.
304 textAngle : `float`, optional
306 label : `str`, optional
307 Label to store this dot
in the internal list.
309 dataTable = Table([{'x': c,
'y': r}])
311 self.
_viewer.marker = {
'type': self.
markerDict[symb],
'color': ctype,
'radius': size}
312 self.
_viewer.add_markers(dataTable, marker_name=label)
315 Line = self.
_canvas.get_draw_class(
'line')
316 Text = self.
_canvas.get_draw_class(
'text')
318 for ds9Cmd
in ds9Regions.dot(symb, c, r, size, fontFamily=
"helvetica", textAngle=
None):
319 tmp = ds9Cmd.split(
'#')
320 cmd = tmp.pop(0).split()
321 comment = tmp.pop(0)
if tmp
else ""
323 cmd, args = cmd[0], cmd[1:]
325 self.
_gingaViewer.canvas.add(Line(*[float(p) - 1
for p
in args], color=ctype),
328 x, y = [float(p) - 1
for p
in args[0:2]]
331 raise RuntimeError(ds9Cmd)
336 """Connect the points, a list of (col,row).
340 points : `list` [`tuple` [`int`, `int`]]
341 Points to connect with lines.
348 self.
_gingaViewer.canvas.add(Line(p0[0], p0[1], p[0], p[1], color=ctype), redraw=self.
_redraw)
351 def beginMarking(self, symb='+', ctype='cyan', size=10, label='interactive'):
352 """Begin interactive mark adding.
356 symb : `str`, optional
357 Symbol to use. Should be one of '+',
'x',
'*',
'o',
'.'.
358 ctype : `str`, optional
360 size : `float`, optional
363 Label to store this marker
in the internal list.
365 self._viewer.start_marking(marker_name=label,
366 marker={'type': self.
markerDict[symb],
'color': ctype,
'radius': size})
369 """End interactive mark adding."""
373 """Get list of markers.
377 label : `str`, optional
378 Marker label to return.
382 table : `astropy.table.Table`
383 Table of markers
with the given label.
385 return self.
_viewer.get_markers(marker_name=label)
392 label : `str`, optional
393 Marker label to clear. If None, all markers are cleared.
396 self.
_viewer.remove_markers(label)
401 """Connect markers with lines.
405 ctype : `str`, optional
406 Color to draw the lines.
407 label : `str`, optional
408 Marker label to connect. Lines are drawn in the order
412 table = self.
_viewer.get_markers(marker_name=label)
415 for rowCount, (x, y)
in enumerate(table.iterrows(
'x',
'y')):
422 """Remove all lines from the display."""
425 def _scale(self, algorithm, min, max, unit, *args, **kwargs):
426 """Set greyscale values.
431 Image scaling algorithm to use.
432 min : `float` or `str`
433 Minimum value to set to black. If a string, should be one of
'zscale' or 'minmax'.
435 Maximum value to set to white.
437 Scaling units. This
is ignored.
443 self.
_gingaViewer.set_autocut_params(
'zscale', contrast=0.25)
445 elif min ==
"minmax":
450 print(
"ginga: ignoring scale unit %s" % unit, file=sys.stderr)
455 """Show the requested display.
457 In this case, embed it in the notebook (equivalent to
458 Display.get_viewer().show(); see also
459 Display.get_viewer().
embed() N.b. These command *must* be the
460 last entry
in their cell
468 """Zoom by specified amount
478 """Pan to (colc, rowc)
483 Column to center in viewer (0-based coordinate).
485 Row to center
in viewer (0-based coordinate).
490 """Listen for a key press on a frame in DS9 and return an event.
495 Event with (key, x, y).
502 """A class to adapt the LSST Wcs class for Ginga.
504 This was taken largely from the afw.display.ginga package.
508 wcs : `ginga.util.wcsmod.wcs_astropy`
509 WCS to adapt
for Ginga.
515 """Return (ra, dec) in degrees given a position in pixels.
519 idxs : `list` [`tuple` [`float`, `float`]]
520 Pixel locations to convert.
521 coords : `str`, optional
522 This parameter is ignored.
526 RA position
in degrees.
528 DEC position
in degrees.
532 return ra.asDegrees(), dec.asDegrees()
535 """Return (ra, dec) in degrees given a position in pixels.
539 idxs : `list` [`tuple` [`float`, `float`]]
540 Pixel locations to convert.
541 system : `str`, optional
542 This parameter is ignored.
543 coords : `str`, optional
544 This parameter
is ignored.
549 RA position
in degrees.
551 DEC position
in degrees.
555 def radectopix(self, ra_deg, dec_deg, coords='data', naxispath=None):
556 """Return (x, y) in pixels given (ra, dec) in degrees
560 ra_deg : `list` [`float`]
561 RA position in degrees.
562 dec_deg : `list` [`float`]
563 DEC position
in degrees.
564 coords : `str`, optional
565 This parameter
is ignored.
566 naxispath : `str`, optional
567 This parameter
is ignored.
571 out : `tuple` [`list` [`float, `float`]]
572 Image coordates
for input positions.
574 return self.
_wcs.
skyToPixel(ra_deg*afwGeom.degrees, dec_deg*afwGeom.degrees)
std::vector< SchemaItem< Flag > > * items
A class to contain the data, WCS, and other information needed to describe an image of the sky.
A class to represent a 2-dimensional array of pixels.
Represent a 2-dimensional array of bitmask pixels.
daf::base::PropertyList * list