24 "WHITE",
"BLACK",
"RED",
"GREEN",
"BLUE",
"CYAN",
"MAGENTA",
"YELLOW",
"ORANGE",
"IGNORE",
25 "Display",
"Event",
"noop_callback",
"h_callback",
26 "setDefaultBackend",
"getDefaultBackend",
27 "setDefaultFrame",
"getDefaultFrame",
"incrDefaultFrame",
28 "setDefaultMaskTransparency",
"setDefaultMaskPlaneColor",
29 "getDisplay",
"delAllDisplays",
57 """Return the ``DisplayImpl`` for the named backend
62 Name of device. Should be importable, either absolutely or relative to
lsst.display
66 Arguments passed to DisplayImpl.__init__
68 Keywords arguments passed to DisplayImpl.__init__
77 display = afwDisplay.Display(backend=
"ds9")
89 candidateBackends = (f
"lsst.display.{backend}", backend, f
".{backend}", f
"lsst.afw.display.{backend}")
90 for dt
in candidateBackends:
94 if dt.startswith(
"."):
95 impargs[
"package"] =
"lsst.display"
97 _disp = importlib.import_module(dt, **impargs)
100 if hasattr(_disp,
"DisplayImpl"):
104 except (ImportError, SystemError)
as e:
110 if not _disp
or not hasattr(_disp.DisplayImpl,
"_show"):
112 e = ImportError(f
"Could not load the requested backend: {backend} "
113 f
"(tried {', '.join(candidateBackends)}, but none worked).")
120 _impl = _disp.DisplayImpl(display, *args, **kwargs)
121 if not hasattr(_impl,
"frame"):
122 _impl.frame = display.frame
130 """Create an object able to display images and overplot glyphs
135 An identifier for the display
139 Arguments to
pass to the backend
141 Arguments to
pass to the backend
144 _defaultBackend = None
146 _defaultMaskPlaneColor = dict(
153 DETECTED_NEGATIVE=CYAN,
160 _defaultMaskTransparency = {}
161 _defaultImageColormap =
"gray"
163 def __init__(self, frame=None, backend=None, *args, **kwargs):
168 if Display._defaultBackend
is None:
174 backend = Display._defaultBackend
188 for ik
in range(ord(
'a'), ord(
'z') + 1):
193 for k
in (
'Return',
'Shift_L',
'Shift_R'):
196 for k
in (
'q',
'Escape'):
199 def _h_callback(k, x, y):
204 print(
" %-6s %s" % (k, doc.split(
"\n")[0]
if doc
else "???"))
208 Display._displays[frame] = self
211 """Support for python's with statement
216 """Support for python's with statement
224 """Return the attribute of ``self._impl``, or ``._impl`` if it is requested
229 name of the attribute requested
234 the attribute of self._impl for the requested name
238 return object.__getattr__(self, name)
240 if not (hasattr(self,
"_impl")
and self.
_impl):
241 raise AttributeError(
"Device has no _impl attached")
244 return getattr(self.
_impl, name)
245 except AttributeError:
246 raise AttributeError(
247 f
"Device {self.name} has no attribute \"{name}\"")
250 if getattr(self,
"_impl",
None)
is not None:
255 if self.
frame in Display._displays:
256 del Display._displays[self.
frame]
260 """The backend's verbosity
262 return self.
_impl.verbose
267 self.
_impl.verbose = value
270 return f
"Display[{self.frame}]"
279 except Exception
as e:
281 f
"Unable to set backend to {backend}: \"{e}\"")
283 Display._defaultBackend = backend
287 return Display._defaultBackend
291 """Set the default frame for display
293 Display._defaultFrame = frame
297 """Get the default frame for display
299 return Display._defaultFrame
303 """Increment the default frame for display
305 Display._defaultFrame += 1
306 return Display._defaultFrame
310 if hasattr(maskPlaneTransparency,
"copy"):
311 maskPlaneTransparency = maskPlaneTransparency.copy()
313 Display._defaultMaskTransparency = maskPlaneTransparency
317 """Set the default mapping from mask plane names to colors
321 name : `str` or `dict`
322 name of mask plane,
or a dict mapping names to colors
323 If name
is `
None`, use the hard-coded default dictionary
325 Desired color,
or `
None`
if name
is a dict
329 name = Display._defaultMaskPlaneColor
331 if isinstance(name, dict):
333 for k, v
in name.items():
339 Display._defaultMaskPlaneColor[name] = color
343 """Set the default colormap for images
348 Name of colormap, as interpreted by the backend
352 The only colormaps that all backends are required to honor
353 (
if they pay any attention to setImageColormap) are
"gray" and "grey"
356 Display._defaultImageColormap = cmap
359 """Set the colormap to use for images
364 Name of colormap, as interpreted by the backend
368 The only colormaps that all backends are required to honor
369 (
if they pay any attention to setImageColormap) are
"gray" and "grey"
372 self._impl._setImageColormap(cmap)
375 def getDisplay(frame=None, backend=None, create=True, verbose=False, *args, **kwargs):
376 """Return a specific `Display`, creating it if need be
381 The desired frame (`None` => use defaultFrame (see `~Display.setDefaultFrame`))
383 create the specified frame using this backend (
or the default
if
384 `
None`)
if it doesn
't already exist. If ``backend == ""``, it's an
385 error to specify a non-existent ``frame``.
387 create the display
if it doesn
't already exist.
389 Allow backend to be chatty
391 arguments passed to `Display` constructor
393 keyword arguments passed to `Display` constructor
397 frame = Display._defaultFrame
399 if frame
not in Display._displays:
401 raise RuntimeError(f
"Frame {frame} does not exist")
403 Display._displays[frame] =
Display(
404 frame, backend, verbose=verbose, *args, **kwargs)
406 Display._displays[frame].verbose = verbose
407 return Display._displays[frame]
411 """Delete and close all known displays
413 for disp
in list(Display._displays.values()):
415 Display._displays = {}
418 """A generator for "standard" colors
423 Don't include `BLACK` and `WHITE`
430 colorGenerator = interface.maskColorGenerator(omitBW=True)
432 print(p, next(colorGenerator))
434 _maskColors = [WHITE, BLACK, RED, GREEN,
435 BLUE, CYAN, MAGENTA, YELLOW, ORANGE]
440 color = _maskColors[i%len(_maskColors)]
441 if omitBW
and color
in (BLACK, WHITE):
447 """Request that mask plane name be displayed as color
451 name : `str` or `dict`
452 Name of mask plane
or a dictionary of name -> colorName
454 The name of the color to use (must be `
None`
if ``name``
is a `dict`)
456 Colors may be specified
as any X11-compliant string (e.g. `
"orchid"`),
or by one
457 of the following constants
in `
lsst.afw.display` : `BLACK`, `WHITE`, `RED`, `BLUE`,
458 `GREEN`, `CYAN`, `MAGENTA`, `YELLOW`.
460 If the color
is "ignore" (
or `IGNORE`) then that mask plane
is not displayed
462 The advantage of using the symbolic names
is that the python interpreter can detect typos.
465 if isinstance(name, dict):
467 for k, v
in name.items():
474 """Return the color associated with the specified mask plane name
479 Desired mask plane; if `
None`,
return entire dict
493 """Specify display's mask transparency (percent); or `None` to not set it when loading masks
496 if isinstance(transparency, dict):
498 for k, v
in transparency.items():
502 if transparency
is not None and (transparency < 0
or transparency > 100):
504 "Mask transparency should be in the range [0, 100]; clipping", file=sys.stderr)
510 if transparency
is not None:
511 self.
_impl._setMaskTransparency(transparency, name)
514 """Return the current display's mask transparency
517 return self.
_impl._getMaskTransparency(name)
520 """Uniconify and Raise display.
524 Throws an exception if frame doesn
't exit
526 return self.
_impl._show()
528 def __addMissingMaskPlanes(self, mask):
529 """Assign colours to any missing mask planes found in mask"""
531 maskPlanes = mask.getMaskPlaneDict()
532 nMaskPlanes =
max(maskPlanes.values()) + 1
535 for key
in maskPlanes:
536 planes[maskPlanes[key]] = key
539 for p
in range(nMaskPlanes):
544 def mtv(self, data, title="", wcs=None):
545 """Display an `~lsst.afw.image.Image` or `~lsst.afw.image.Mask` on a display
549 Historical note: the name "mtv" comes
from Jim Gunn
's forth imageprocessing
550 system, Mirella (named after Mirella Freni); The "m" stands
for Mirella.
552 if hasattr(data,
"getXY0"):
553 self.
_xy0 = data.getXY0()
561 "You may not specify a wcs with an Exposure")
562 data, wcs = data.getMaskedImage(), data.getWcs()
570 self.
_xy0 = data.getXY0()
573 self.
_impl._mtv(data,
None, wcs, title)
581 self.
_impl._mtv(afwImage.ImageI(data.getArray()), data, wcs, title)
585 self.
_impl._mtv(data.getImage(), data.getMask(), wcs, title)
587 raise RuntimeError(f
"Unsupported type {data!r}")
593 """A class intended to be used with python's with statement
600 self.
_impl._buffer(
True)
603 self.
_impl._buffer(
False)
607 """Return a class intended to be used with python's with statement
613 with display.Buffering():
614 display.dot(
"+", xc, yc)
624 """Erase the specified display frame
628 def dot(self, symb, c, r, size=2, ctype=None, origin=afwImage.PARENT, *args, **kwargs):
629 """Draw a symbol onto the specified display frame
645 Draw an ellipse
with moments (Mxx, Mxy, Myy) (argument size
is ignored)
647 Draw the ellipse (argument size
is ignored). N.b. objects
651 Interpreted
as a string to be drawn.
653 The column
and row where the symbol
is drawn [0-based coordinates]
655 Size of symbol,
in pixels
657 The desired color, either e.g. `lsst.afw.display.RED`
or a color name known to X11
658 origin : `lsst.afw.image.ImageOrigin`
659 Coordinate system
for the given positions.
661 Extra arguments to backend
663 Extra keyword arguments to backend
665 if isinstance(symb, int):
668 if origin == afwImage.PARENT
and self.
_xy0 is not None:
673 if isinstance(symb, afwGeom.ellipses.BaseCore)
or re.search(
r"^@:", symb):
675 mat = re.search(
r"^@:([^,]+),([^,]+),([^,]+)", symb)
680 mxx, mxy, myy = [float(_)
for _
in mat.groups()]
683 symb = afwGeom.ellipses.Axes(symb)
685 self.
_impl._dot(symb, c, r, size, ctype, **kwargs)
687 def line(self, points, origin=afwImage.PARENT, symbs=False, ctype=None, size=0.5):
688 """Draw a set of symbols or connect points
694 origin : `lsst.afw.image.ImageOrigin`
695 Coordinate system for the given positions.
696 symbs : `bool`
or sequence
697 If ``symbs``
is `
True`, draw points at the specified points using the desired symbol,
698 otherwise connect the dots.
700 If ``symbs`` supports indexing (which includes a string -- caveat emptor) the
701 elements are used to label the points
703 ``ctype``
is the name of a color (e.g.
'red')
710 symbs = len(points)*
list(symbs)
712 for i, xy
in enumerate(points):
713 self.
dot(symbs[i], *xy, size=size, ctype=ctype)
716 if origin == afwImage.PARENT
and self.
_xy0 is not None:
718 _points =
list(points)
719 for i, p
in enumerate(points):
720 _points[i] = (p[0] - x0, p[1] - y0)
723 self.
_impl._drawLines(points, ctype)
728 def scale(self, algorithm, min, max=None, unit=None, *args, **kwargs):
729 """Set the range of the scaling from DN in the image to the image display
734 Desired scaling (e.g. "linear" or "asinh")
736 Minimum value,
or "minmax" or "zscale"
738 Maximum value (must be `
None`
for minmax|zscale)
740 Units
for min
and max (e.g. Percent, Absolute, Sigma; `
None`
if min==minmax|zscale)
742 Optional arguments to the backend
744 Optional keyword arguments to the backend
746 if min
in (
"minmax",
"zscale"):
747 assert max
is None, f
"You may not specify \"{min}\" and max"
748 assert unit
is None, f
"You may not specify \"{min}\" and unit"
750 raise RuntimeError(
"Please specify max")
752 self.
_impl._scale(algorithm, min, max, unit, *args, **kwargs)
757 def zoom(self, zoomfac=None, colc=None, rowc=None, origin=afwImage.PARENT):
758 """Zoom frame by specified amount, optionally panning also
761 if (rowc
and colc
is None)
or (colc
and rowc
is None):
763 "Please specify row and column center to pan about")
766 if origin == afwImage.PARENT
and self.
_xy0 is not None:
771 self.
_impl._pan(colc, rowc)
773 if zoomfac
is None and rowc
is None:
776 if zoomfac
is not None:
777 self.
_impl._zoom(zoomfac)
779 def pan(self, colc=None, rowc=None, origin=afwImage.PARENT):
785 the coordinates to pan to
786 origin : `lsst.afw.image.ImageOrigin`
787 Coordinate system for the given positions.
794 self.zoom(None, colc, rowc, origin)
797 """Enter an interactive loop, listening for key presses in display and firing callbacks.
799 Exit with ``q``, ``CR``, ``ESC``,
or any other callback function that returns a `
True` value.
801 interactFinished = False
803 while not interactFinished:
804 ev = self.
_impl._getEvent()
807 k, x, y = ev.k, ev.x, ev.y
810 logger.warn(
"No callback registered for {0}".format(k))
813 interactFinished = self.
_callbacks[k](k, x, y)
814 except Exception
as e:
816 "Display._callbacks['{0}']({0},{1},{2}) failed: {3}".format(k, x, y, e))
819 """Set the callback for a key
824 The key to assign the callback to
826 The callback assigned to ``k``
832 The callback previously assigned to ``k``.
839 f
"Key '{k}' is already in use by display, so I can't add a callback for it")
842 self.
_callbacks[k] = func
if func
else noop_callback
849 """Return all callback keys
854 If `True` only
return keys that do something
858 not (onlyActive
and func == noop_callback)])
866 """A class to handle events such as key presses in image display windows
869 def __init__(self, k, x=float(
'nan'), y=float(
'nan')):
875 return f
"{self.k} ({self.x:.2f}, {self.y:.2f}"
894 print(
"Enter q or <ESC> to leave interactive mode, h for this help, or a letter to fire a callback")
905 Display.setDefaultBackend(backend)
909 return Display.getDefaultBackend()
913 return Display.setDefaultFrame(frame)
917 """Get the default frame for display
919 return Display.getDefaultFrame()
923 """Increment the default frame for display
925 return Display.incrDefaultFrame()
929 return Display.setDefaultMaskTransparency(maskPlaneTransparency)
933 """Set the default mapping from mask plane names to colors
937 name : `str` or `dict`
938 name of mask plane,
or a dict mapping names to colors.
939 If ``name``
is `
None`, use the hard-coded default dictionary
941 Desired color,
or `
None`
if ``name``
is a dict
944 return Display.setDefaultMaskPlaneColor(name, color)
947def getDisplay(frame=None, backend=None, create=True, verbose=False, *args, **kwargs):
948 """Return a specific `Display`, creating it if need be
953 The desired frame (`None` => use defaultFrame (see `setDefaultFrame`))
955 Create the specified frame using this backend (
or the default
if
956 `
None`)
if it doesn
't already exist. If ``backend == ""``, it's an
957 error to specify a non-existent ``frame``.
959 Create the display
if it doesn
't already exist.
961 Allow backend to be chatty
963 arguments passed to `Display` constructor
965 keyword arguments passed to `Display` constructor
972 return Display.getDisplay(frame, backend, create, verbose, *args, **kwargs)
976 """Delete and close all known displays
978 return Display.delAllDisplays()
std::vector< SchemaItem< Flag > > * items
mtv(self, data, title="", wcs=None)
setMaskTransparency(self, transparency=None, name=None)
getActiveCallbackKeys(self, onlyActive=True)
setDefaultBackend(backend)
getMaskPlaneColor(self, name=None)
setDefaultImageColormap(cmap)
dot(self, symb, c, r, size=2, ctype=None, origin=afwImage.PARENT, *args, **kwargs)
line(self, points, origin=afwImage.PARENT, symbs=False, ctype=None, size=0.5)
setDefaultMaskTransparency(maskPlaneTransparency={})
pan(self, colc=None, rowc=None, origin=afwImage.PARENT)
getMaskTransparency(self, name=None)
setCallback(self, k, func=None, noRaise=False)
setMaskPlaneColor(self, name, color=None)
setDefaultMaskPlaneColor(name=None, color=None)
scale(self, algorithm, min, max=None, unit=None, *args, **kwargs)
__addMissingMaskPlanes(self, mask)
__init__(self, frame=None, backend=None, *args, **kwargs)
maskColorGenerator(self, omitBW=True)
zoom(self, zoomfac=None, colc=None, rowc=None, origin=afwImage.PARENT)
setImageColormap(self, cmap)
__init__(self, k, x=float('nan'), y=float('nan'))
An ellipse core for the semimajor/semiminor axis and position angle parametrization (a,...
A base class for parametrizations of the "core" of an ellipse - the ellipticity and size.
An ellipse core with quadrupole moments as parameters.
A container for an Image and its associated metadata.
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.
A class to manipulate images, masks, and variance as a single object.
static Log getLogger(Log const &logger)
daf::base::PropertyList * list
setDefaultMaskTransparency(maskPlaneTransparency={})
setDefaultMaskPlaneColor(name=None, color=None)
_makeDisplayImpl(display, backend, *args, **kwargs)
setDefaultBackend(backend)
std::shared_ptr< SkyWcs > makeSkyWcs(daf::base::PropertySet &metadata, bool strip=false)
Construct a SkyWcs from FITS keywords.