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",
56 def _makeDisplayImpl(display, backend, *args, **kwargs):
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__
75 import lsst.afw.display as afwDisplay
76 display = afwDisplay.Display(display=1, backend="ds9")
80 _makeDisplayImpl(..., "ds9", 1)
81 and import the ds9 implementation of ``DisplayImpl`` from `lsst.display.ds9`
85 for dt
in (f
"lsst.display.{backend}", backend, f
".{backend}", f
"lsst.afw.display.{backend}"):
89 if dt.startswith(
"."):
90 impargs[
"package"] =
"lsst.display"
92 _disp = importlib.import_module(dt, **impargs)
94 except (ImportError, SystemError)
as e:
100 if not _disp
or not hasattr(_disp.DisplayImpl,
"_show"):
106 "Could not load the requested backend: {}".
format(backend))
109 _impl = _disp.DisplayImpl(display, *args, **kwargs)
110 if not hasattr(_impl,
"frame"):
111 _impl.frame = display.frame
119 """Create an object able to display images and overplot glyphs
124 An identifier for the display
126 The backend to use (defaults to value set by setDefaultBackend())
128 Arguments to pass to the backend
130 Arguments to pass to the backend
133 _defaultBackend =
None
135 _defaultMaskPlaneColor = dict(
142 DETECTED_NEGATIVE=CYAN,
149 _defaultMaskTransparency = {}
150 _defaultImageColormap =
"gray"
152 def __init__(self, frame=None, backend=None, *args, **kwargs):
157 if Display._defaultBackend
is None:
163 backend = Display._defaultBackend
166 self.
_impl_impl = _makeDisplayImpl(self, backend, *args, **kwargs)
177 for ik
in range(ord(
'a'), ord(
'z') + 1):
180 self.
setCallbacksetCallback(k.upper(), noRaise=
True)
182 for k
in (
'Return',
'Shift_L',
'Shift_R'):
185 for k
in (
'q',
'Escape'):
186 self.
setCallbacksetCallback(k,
lambda k, x, y:
True)
188 def _h_callback(k, x, y):
193 print(
" %-6s %s" % (k, doc.split(
"\n")[0]
if doc
else "???"))
197 Display._displays[frame] = self
200 """Support for python's with statement
205 """Support for python's with statement
213 """Return the attribute of ``self._impl``, or ``._impl`` if it is requested
218 name of the attribute requested
223 the attribute of self._impl for the requested name
227 return object.__getattr__(self, name)
229 if not (hasattr(self,
"_impl")
and self.
_impl_impl):
230 raise AttributeError(
"Device has no _impl attached")
233 return getattr(self.
_impl_impl, name)
234 except AttributeError:
235 raise AttributeError(
236 f
"Device {self.name} has no attribute \"{name}\"")
239 if getattr(self,
"_impl",
None)
is not None:
240 self.
_impl_impl._close()
242 self.
_impl_impl =
None
244 if self.
frameframe
in Display._displays:
245 del Display._displays[self.
frameframe]
249 """The backend's verbosity
251 return self.
_impl_impl.verbose
256 self.
_impl_impl.verbose = value
259 return f
"Display[{self.frame}]"
267 _makeDisplayImpl(
None, backend)
268 except Exception
as e:
270 f
"Unable to set backend to {backend}: \"{e}\"")
272 Display._defaultBackend = backend
276 return Display._defaultBackend
280 """Set the default frame for display
282 Display._defaultFrame = frame
286 """Get the default frame for display
288 return Display._defaultFrame
292 """Increment the default frame for display
294 Display._defaultFrame += 1
295 return Display._defaultFrame
299 if hasattr(maskPlaneTransparency,
"copy"):
300 maskPlaneTransparency = maskPlaneTransparency.copy()
302 Display._defaultMaskTransparency = maskPlaneTransparency
306 """Set the default mapping from mask plane names to colors
310 name : `str` or `dict`
311 name of mask plane, or a dict mapping names to colors
312 If name is `None`, use the hard-coded default dictionary
314 Desired color, or `None` if name is a dict
318 name = Display._defaultMaskPlaneColor
320 if isinstance(name, dict):
322 for k, v
in name.items():
328 Display._defaultMaskPlaneColor[name] = color
332 """Set the default colormap for images
337 Name of colormap, as interpreted by the backend
341 The only colormaps that all backends are required to honor
342 (if they pay any attention to setImageColormap) are "gray" and "grey"
345 Display._defaultImageColormap = cmap
348 """Set the colormap to use for images
353 Name of colormap, as interpreted by the backend
357 The only colormaps that all backends are required to honor
358 (if they pay any attention to setImageColormap) are "gray" and "grey"
361 self.
_impl_impl._setImageColormap(cmap)
364 def getDisplay(frame=None, backend=None, create=True, verbose=False, *args, **kwargs):
365 """Return a specific `Display`, creating it if need be
370 The desired frame (`None` => use defaultFrame (see `~Display.setDefaultFrame`))
372 create the specified frame using this backend (or the default if
373 `None`) if it doesn't already exist. If ``backend == ""``, it's an
374 error to specify a non-existent ``frame``.
376 create the display if it doesn't already exist.
378 Allow backend to be chatty
380 arguments passed to `Display` constructor
382 keyword arguments passed to `Display` constructor
386 frame = Display._defaultFrame
388 if frame
not in Display._displays:
390 raise RuntimeError(f
"Frame {frame} does not exist")
392 Display._displays[frame] =
Display(
393 frame, backend, verbose=verbose, *args, **kwargs)
395 Display._displays[frame].verbose = verbose
396 return Display._displays[frame]
400 """Delete and close all known displays
402 for disp
in list(Display._displays.values()):
404 Display._displays = {}
407 """A generator for "standard" colors
412 Don't include `BLACK` and `WHITE`
419 colorGenerator = interface.maskColorGenerator(omitBW=True)
421 print p, next(colorGenerator)
423 _maskColors = [WHITE, BLACK, RED, GREEN,
424 BLUE, CYAN, MAGENTA, YELLOW, ORANGE]
429 color = _maskColors[i%len(_maskColors)]
430 if omitBW
and color
in (BLACK, WHITE):
436 """Request that mask plane name be displayed as color
440 name : `str` or `dict`
441 Name of mask plane or a dictionary of name -> colorName
443 The name of the color to use (must be `None` if ``name`` is a `dict`)
445 Colors may be specified as any X11-compliant string (e.g. `"orchid"`), or by one
446 of the following constants in `lsst.afw.display` : `BLACK`, `WHITE`, `RED`, `BLUE`,
447 `GREEN`, `CYAN`, `MAGENTA`, `YELLOW`.
449 If the color is "ignore" (or `IGNORE`) then that mask plane is not displayed
451 The advantage of using the symbolic names is that the python interpreter can detect typos.
454 if isinstance(name, dict):
456 for k, v
in name.items():
463 """Return the color associated with the specified mask plane name
468 Desired mask plane; if `None`, return entire dict
477 """Specify display's mask transparency (percent); or `None` to not set it when loading masks
480 if isinstance(transparency, dict):
482 for k, v
in transparency.items():
486 if transparency
is not None and (transparency < 0
or transparency > 100):
488 "Mask transparency should be in the range [0, 100]; clipping", file=sys.stderr)
494 if transparency
is not None:
495 self.
_impl_impl._setMaskTransparency(transparency, name)
498 """Return the current display's mask transparency
501 return self.
_impl_impl._getMaskTransparency(name)
504 """Uniconify and Raise display.
508 Throws an exception if frame doesn't exit
510 return self.
_impl_impl._show()
512 def mtv(self, data, title="", wcs=None):
513 """Display an `~lsst.afw.image.Image` or `~lsst.afw.image.Mask` on a display
517 Historical note: the name "mtv" comes from Jim Gunn's forth imageprocessing
518 system, Mirella (named after Mirella Freni); The "m" stands for Mirella.
520 if hasattr(data,
"getXY0"):
521 self.
_xy0_xy0 = data.getXY0()
529 "You may not specify a wcs with an Exposure")
530 data, wcs = data.getMaskedImage(), data.getWcs()
538 self.
_xy0_xy0 = data.getXY0()
541 self.
_impl_impl._mtv(data,
None, wcs, title)
548 self.
_impl_impl._mtv(afwImage.ImageI(data.getArray()), data, wcs, title)
551 self.
_impl_impl._mtv(data.getImage(), data.getMask(), wcs, title)
553 raise RuntimeError(f
"Unsupported type {data!r}")
559 """A class intended to be used with python's with statement
563 self.
_impl_impl = _impl
566 self.
_impl_impl._buffer(
True)
569 self.
_impl_impl._buffer(
False)
570 self.
_impl_impl._flush()
573 """Return a class intended to be used with python's with statement
579 with display.Buffering():
580 display.dot("+", xc, yc)
587 self.
_impl_impl._flush()
590 """Erase the specified display frame
592 self.
_impl_impl._erase()
594 def dot(self, symb, c, r, size=2, ctype=None, origin=afwImage.PARENT, *args, **kwargs):
595 """Draw a symbol onto the specified display frame
611 Draw an ellipse with moments (Mxx, Mxy, Myy) (argument size is ignored)
612 `lsst.afw.geom.ellipses.BaseCore`
613 Draw the ellipse (argument size is ignored). N.b. objects
614 derived from `~lsst.afw.geom.ellipses.BaseCore` include
615 `~lsst.afw.geom.ellipses.Axes` and `~lsst.afw.geom.ellipses.Quadrupole`.
617 Interpreted as a string to be drawn.
619 The column and row where the symbol is drawn [0-based coordinates]
621 Size of symbol, in pixels
623 The desired color, either e.g. `lsst.afw.display.RED` or a color name known to X11
624 origin : `lsst.afw.image.ImageOrigin`
625 Coordinate system for the given positions.
627 Extra arguments to backend
629 Extra keyword arguments to backend
631 if isinstance(symb, int):
634 if origin == afwImage.PARENT
and self.
_xy0_xy0
is not None:
635 x0, y0 = self.
_xy0_xy0
639 if isinstance(symb, afwGeom.ellipses.BaseCore)
or re.search(
r"^@:", symb):
641 mat = re.search(
r"^@:([^,]+),([^,]+),([^,]+)", symb)
646 mxx, mxy, myy = [float(_)
for _
in mat.groups()]
649 symb = afwGeom.ellipses.Axes(symb)
651 self.
_impl_impl._dot(symb, c, r, size, ctype, **kwargs)
653 def line(self, points, origin=afwImage.PARENT, symbs=False, ctype=None, size=0.5):
654 """Draw a set of symbols or connect points
660 origin : `lsst.afw.image.ImageOrigin`
661 Coordinate system for the given positions.
662 symbs : `bool` or sequence
663 If ``symbs`` is `True`, draw points at the specified points using the desired symbol,
664 otherwise connect the dots.
666 If ``symbs`` supports indexing (which includes a string -- caveat emptor) the
667 elements are used to label the points
669 ``ctype`` is the name of a color (e.g. 'red')
676 symbs = len(points)*
list(symbs)
678 for i, xy
in enumerate(points):
679 self.
dotdot(symbs[i], *xy, size=size, ctype=ctype)
682 if origin == afwImage.PARENT
and self.
_xy0_xy0
is not None:
683 x0, y0 = self.
_xy0_xy0
684 _points =
list(points)
685 for i, p
in enumerate(points):
686 _points[i] = (p[0] - x0, p[1] - y0)
689 self.
_impl_impl._drawLines(points, ctype)
694 def scale(self, algorithm, min, max=None, unit=None, *args, **kwargs):
695 """Set the range of the scaling from DN in the image to the image display
700 Desired scaling (e.g. "linear" or "asinh")
702 Minimum value, or "minmax" or "zscale"
704 Maximum value (must be `None` for minmax|zscale)
706 Units for min and max (e.g. Percent, Absolute, Sigma; `None` if min==minmax|zscale)
708 Optional arguments to the backend
710 Optional keyword arguments to the backend
712 if min
in (
"minmax",
"zscale"):
713 assert max
is None, f
"You may not specify \"{min}\" and max"
714 assert unit
is None, f
"You may not specify \"{min}\" and unit"
716 raise RuntimeError(
"Please specify max")
718 self.
_impl_impl._scale(algorithm, min, max, unit, *args, **kwargs)
723 def zoom(self, zoomfac=None, colc=None, rowc=None, origin=afwImage.PARENT):
724 """Zoom frame by specified amount, optionally panning also
727 if (rowc
and colc
is None)
or (colc
and rowc
is None):
729 "Please specify row and column center to pan about")
732 if origin == afwImage.PARENT
and self.
_xy0_xy0
is not None:
733 x0, y0 = self.
_xy0_xy0
737 self.
_impl_impl._pan(colc, rowc)
739 if zoomfac
is None and rowc
is None:
742 if zoomfac
is not None:
743 self.
_impl_impl._zoom(zoomfac)
745 def pan(self, colc=None, rowc=None, origin=afwImage.PARENT):
751 the coordinates to pan to
752 origin : `lsst.afw.image.ImageOrigin`
753 Coordinate system for the given positions.
760 self.
zoomzoom(
None, colc, rowc, origin)
763 """Enter an interactive loop, listening for key presses in display and firing callbacks.
765 Exit with ``q``, ``CR``, ``ESC``, or any other callback function that returns a `True` value.
767 interactFinished =
False
769 while not interactFinished:
770 ev = self.
_impl_impl._getEvent()
773 k, x, y = ev.k, ev.x, ev.y
776 logger.warn(
"No callback registered for {0}".
format(k))
779 interactFinished = self.
_callbacks_callbacks[k](k, x, y)
780 except Exception
as e:
782 "Display._callbacks['{0}']({0},{1},{2}) failed: {3}".
format(k, x, y, e))
785 """Set the callback for a key
790 The key to assign the callback to
792 The callback assigned to ``k``
798 The callback previously assigned to ``k``.
805 f
"Key '{k}' is already in use by display, so I can't add a callback for it")
808 self.
_callbacks_callbacks[k] = func
if func
else noop_callback
815 """Return all callback keys
820 If `True` only return keys that do something
824 not (onlyActive
and func == noop_callback)])
832 """A class to handle events such as key presses in image display windows
835 def __init__(self, k, x=float(
'nan'), y=float(
'nan')):
841 return f
"{self.k} ({self.x:.2f}, {self.y:.2f}"
860 print(
"Enter q or <ESC> to leave interactive mode, h for this help, or a letter to fire a callback")
871 Display.setDefaultBackend(backend)
875 return Display.getDefaultBackend()
879 return Display.setDefaultFrame(frame)
883 """Get the default frame for display
885 return Display.getDefaultFrame()
889 """Increment the default frame for display
891 return Display.incrDefaultFrame()
895 return Display.setDefaultMaskTransparency(maskPlaneTransparency)
899 """Set the default mapping from mask plane names to colors
903 name : `str` or `dict`
904 name of mask plane, or a dict mapping names to colors.
905 If ``name`` is `None`, use the hard-coded default dictionary
907 Desired color, or `None` if ``name`` is a dict
910 return Display.setDefaultMaskPlaneColor(name, color)
913 def getDisplay(frame=None, backend=None, create=True, verbose=False, *args, **kwargs):
914 """Return a specific `Display`, creating it if need be
919 The desired frame (`None` => use defaultFrame (see `setDefaultFrame`))
921 Create the specified frame using this backend (or the default if
922 `None`) if it doesn't already exist. If ``backend == ""``, it's an
923 error to specify a non-existent ``frame``.
925 Create the display if it doesn't already exist.
927 Allow backend to be chatty
929 arguments passed to `Display` constructor
931 keyword arguments passed to `Display` constructor
938 return Display.getDisplay(frame, backend, create, verbose, *args, **kwargs)
942 """Delete and close all known displays
944 return Display.delAllDisplays()
std::vector< SchemaItem< Flag > > * items
def __init__(self, _impl)
def __exit__(self, *args)
def maskColorGenerator(self, omitBW=True)
def setDefaultMaskTransparency(maskPlaneTransparency={})
def dot(self, symb, c, r, size=2, ctype=None, origin=afwImage.PARENT, *args, **kwargs)
def setDefaultImageColormap(cmap)
def zoom(self, zoomfac=None, colc=None, rowc=None, origin=afwImage.PARENT)
def getActiveCallbackKeys(self, onlyActive=True)
def setDefaultBackend(backend)
def line(self, points, origin=afwImage.PARENT, symbs=False, ctype=None, size=0.5)
def __getattr__(self, name)
def setCallback(self, k, func=None, noRaise=False)
def __exit__(self, *args)
def mtv(self, data, title="", wcs=None)
def setMaskTransparency(self, transparency=None, name=None)
def getDisplay(frame=None, backend=None, create=True, verbose=False, *args, **kwargs)
def getMaskPlaneColor(self, name=None)
def setDefaultFrame(frame=0)
def pan(self, colc=None, rowc=None, origin=afwImage.PARENT)
def setMaskPlaneColor(self, name, color=None)
def setImageColormap(self, cmap)
def setDefaultMaskPlaneColor(name=None, color=None)
def scale(self, algorithm, min, max=None, unit=None, *args, **kwargs)
def __init__(self, frame=None, backend=None, *args, **kwargs)
def getMaskTransparency(self, name=None)
def __init__(self, k, x=float('nan'), y=float('nan'))
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
def noop_callback(k, x, y)
def getDisplay(frame=None, backend=None, create=True, verbose=False, *args, **kwargs)
def setDefaultMaskTransparency(maskPlaneTransparency={})
def setDefaultFrame(frame=0)
def setDefaultMaskPlaneColor(name=None, color=None)
def setDefaultBackend(backend)
std::shared_ptr< SkyWcs > makeSkyWcs(daf::base::PropertySet &metadata, bool strip=false)
Construct a SkyWcs from FITS keywords.
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects.
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)