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",
56def _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__
76 display = afwDisplay.Display(display=1, backend=
"ds9")
80 _makeDisplayImpl(...,
"ds9", 1)
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
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 = _makeDisplayImpl(self, backend, *args, **kwargs)
177 for ik
in range(ord(
'a'), ord(
'z') + 1):
182 for k
in (
'Return',
'Shift_L',
'Shift_R'):
185 for k
in (
'q',
'Escape'):
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):
230 raise AttributeError(
"Device has no _impl attached")
233 return getattr(self.
_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:
244 if self.
frame in Display._displays:
245 del Display._displays[self.
frame]
249 """The backend's verbosity
251 return self.
_impl.verbose
256 self.
_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._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
482 """Specify display's mask transparency (percent); or `None` to not set it when loading masks
485 if isinstance(transparency, dict):
487 for k, v
in transparency.items():
491 if transparency
is not None and (transparency < 0
or transparency > 100):
493 "Mask transparency should be in the range [0, 100]; clipping", file=sys.stderr)
499 if transparency
is not None:
500 self.
_impl._setMaskTransparency(transparency, name)
503 """Return the current display's mask transparency
506 return self.
_impl._getMaskTransparency(name)
509 """Uniconify and Raise display.
513 Throws an exception if frame doesn
't exit
515 return self.
_impl._show()
517 def __addMissingMaskPlanes(self, mask):
518 """Assign colours to any missing mask planes found in mask"""
520 maskPlanes = mask.getMaskPlaneDict()
521 nMaskPlanes =
max(maskPlanes.values()) + 1
524 for key
in maskPlanes:
525 planes[maskPlanes[key]] = key
528 for p
in range(nMaskPlanes):
533 def mtv(self, data, title="", wcs=None):
534 """Display an `~lsst.afw.image.Image` or `~lsst.afw.image.Mask` on a display
538 Historical note: the name "mtv" comes
from Jim Gunn
's forth imageprocessing
539 system, Mirella (named after Mirella Freni); The "m" stands
for Mirella.
541 if hasattr(data,
"getXY0"):
542 self.
_xy0 = data.getXY0()
550 "You may not specify a wcs with an Exposure")
551 data, wcs = data.getMaskedImage(), data.getWcs()
559 self.
_xy0 = data.getXY0()
562 self.
_impl._mtv(data,
None, wcs, title)
570 self.
_impl._mtv(afwImage.ImageI(data.getArray()), data, wcs, title)
574 self.
_impl._mtv(data.getImage(), data.getMask(), wcs, title)
576 raise RuntimeError(f
"Unsupported type {data!r}")
582 """A class intended to be used with python's with statement
589 self.
_impl._buffer(
True)
592 self.
_impl._buffer(
False)
596 """Return a class intended to be used with python's with statement
602 with display.Buffering():
603 display.dot(
"+", xc, yc)
613 """Erase the specified display frame
617 def dot(self, symb, c, r, size=2, ctype=None, origin=afwImage.PARENT, *args, **kwargs):
618 """Draw a symbol onto the specified display frame
634 Draw an ellipse
with moments (Mxx, Mxy, Myy) (argument size
is ignored)
636 Draw the ellipse (argument size
is ignored). N.b. objects
640 Interpreted
as a string to be drawn.
642 The column
and row where the symbol
is drawn [0-based coordinates]
644 Size of symbol,
in pixels
646 The desired color, either e.g. `lsst.afw.display.RED`
or a color name known to X11
647 origin : `lsst.afw.image.ImageOrigin`
648 Coordinate system
for the given positions.
650 Extra arguments to backend
652 Extra keyword arguments to backend
654 if isinstance(symb, int):
657 if origin == afwImage.PARENT
and self.
_xy0 is not None:
662 if isinstance(symb, afwGeom.ellipses.BaseCore)
or re.search(
r"^@:", symb):
664 mat = re.search(
r"^@:([^,]+),([^,]+),([^,]+)", symb)
669 mxx, mxy, myy = [float(_)
for _
in mat.groups()]
672 symb = afwGeom.ellipses.Axes(symb)
674 self.
_impl._dot(symb, c, r, size, ctype, **kwargs)
676 def line(self, points, origin=afwImage.PARENT, symbs=False, ctype=None, size=0.5):
677 """Draw a set of symbols or connect points
683 origin : `lsst.afw.image.ImageOrigin`
684 Coordinate system for the given positions.
685 symbs : `bool`
or sequence
686 If ``symbs``
is `
True`, draw points at the specified points using the desired symbol,
687 otherwise connect the dots.
689 If ``symbs`` supports indexing (which includes a string -- caveat emptor) the
690 elements are used to label the points
692 ``ctype``
is the name of a color (e.g.
'red')
699 symbs = len(points)*
list(symbs)
701 for i, xy
in enumerate(points):
702 self.
dot(symbs[i], *xy, size=size, ctype=ctype)
705 if origin == afwImage.PARENT
and self.
_xy0 is not None:
707 _points =
list(points)
708 for i, p
in enumerate(points):
709 _points[i] = (p[0] - x0, p[1] - y0)
712 self.
_impl._drawLines(points, ctype)
717 def scale(self, algorithm, min, max=None, unit=None, *args, **kwargs):
718 """Set the range of the scaling from DN in the image to the image display
723 Desired scaling (e.g. "linear" or "asinh")
725 Minimum value,
or "minmax" or "zscale"
727 Maximum value (must be `
None`
for minmax|zscale)
729 Units
for min
and max (e.g. Percent, Absolute, Sigma; `
None`
if min==minmax|zscale)
731 Optional arguments to the backend
733 Optional keyword arguments to the backend
735 if min
in (
"minmax",
"zscale"):
736 assert max
is None, f
"You may not specify \"{min}\" and max"
737 assert unit
is None, f
"You may not specify \"{min}\" and unit"
739 raise RuntimeError(
"Please specify max")
741 self.
_impl._scale(algorithm, min, max, unit, *args, **kwargs)
746 def zoom(self, zoomfac=None, colc=None, rowc=None, origin=afwImage.PARENT):
747 """Zoom frame by specified amount, optionally panning also
750 if (rowc
and colc
is None)
or (colc
and rowc
is None):
752 "Please specify row and column center to pan about")
755 if origin == afwImage.PARENT
and self.
_xy0 is not None:
760 self.
_impl._pan(colc, rowc)
762 if zoomfac
is None and rowc
is None:
765 if zoomfac
is not None:
766 self.
_impl._zoom(zoomfac)
768 def pan(self, colc=None, rowc=None, origin=afwImage.PARENT):
774 the coordinates to pan to
775 origin : `lsst.afw.image.ImageOrigin`
776 Coordinate system for the given positions.
783 self.zoom(None, colc, rowc, origin)
786 """Enter an interactive loop, listening for key presses in display and firing callbacks.
788 Exit with ``q``, ``CR``, ``ESC``,
or any other callback function that returns a `
True` value.
790 interactFinished = False
792 while not interactFinished:
793 ev = self.
_impl._getEvent()
796 k, x, y = ev.k, ev.x, ev.y
799 logger.warn(
"No callback registered for {0}".format(k))
802 interactFinished = self.
_callbacks[k](k, x, y)
803 except Exception
as e:
805 "Display._callbacks['{0}']({0},{1},{2}) failed: {3}".format(k, x, y, e))
808 """Set the callback for a key
813 The key to assign the callback to
815 The callback assigned to ``k``
821 The callback previously assigned to ``k``.
828 f
"Key '{k}' is already in use by display, so I can't add a callback for it")
831 self.
_callbacks[k] = func
if func
else noop_callback
838 """Return all callback keys
843 If `True` only
return keys that do something
847 not (onlyActive
and func == noop_callback)])
855 """A class to handle events such as key presses in image display windows
858 def __init__(self, k, x=float(
'nan'), y=float(
'nan')):
864 return f
"{self.k} ({self.x:.2f}, {self.y:.2f}"
883 print(
"Enter q or <ESC> to leave interactive mode, h for this help, or a letter to fire a callback")
894 Display.setDefaultBackend(backend)
898 return Display.getDefaultBackend()
902 return Display.setDefaultFrame(frame)
906 """Get the default frame for display
908 return Display.getDefaultFrame()
912 """Increment the default frame for display
914 return Display.incrDefaultFrame()
918 return Display.setDefaultMaskTransparency(maskPlaneTransparency)
922 """Set the default mapping from mask plane names to colors
926 name : `str` or `dict`
927 name of mask plane,
or a dict mapping names to colors.
928 If ``name``
is `
None`, use the hard-coded default dictionary
930 Desired color,
or `
None`
if ``name``
is a dict
933 return Display.setDefaultMaskPlaneColor(name, color)
936def getDisplay(frame=None, backend=None, create=True, verbose=False, *args, **kwargs):
937 """Return a specific `Display`, creating it if need be
942 The desired frame (`None` => use defaultFrame (see `setDefaultFrame`))
944 Create the specified frame using this backend (
or the default
if
945 `
None`)
if it doesn
't already exist. If ``backend == ""``, it's an
946 error to specify a non-existent ``frame``.
948 Create the display
if it doesn
't already exist.
950 Allow backend to be chatty
952 arguments passed to `Display` constructor
954 keyword arguments passed to `Display` constructor
961 return Display.getDisplay(frame, backend, create, verbose, *args, **kwargs)
965 """Delete and close all known displays
967 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 __addMissingMaskPlanes(self, mask)
def setMaskTransparency(self, transparency=None, name=None)
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 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
def noop_callback(k, x, y)
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.