30 "drawBBox",
"drawFootprint",
"drawCoaddInputs",
34 def _getDisplayFromDisplayOrFrame(display, frame=None):
35 """Return an `lsst.afw.display.Display` given either a display or a frame ID.
39 If the two arguments are consistent, return the desired display; if they are not,
40 raise a `RuntimeError` exception.
42 If the desired display is `None`, return `None`;
43 if ``(display, frame) == ("deferToFrame", None)``, return the default display
49 if display
in (
"deferToFrame",
None):
50 if display
is None and frame
is None:
56 if display
and not hasattr(display,
"frame"):
57 raise RuntimeError(f
"display == {display} doesn't support .frame")
59 if frame
and display
and display.frame != frame:
60 raise RuntimeError(
"Please specify display *or* frame")
65 display = afwDisplay.getDisplay(frame, create=
True)
71 """A class to handle mosaics of one or more identically-sized images
72 (or `~lsst.afw.image.Mask` or `~lsst.afw.image.MaskedImage`)
76 Note that this mosaic is a patchwork of the input images; if you want to
77 make a mosaic of a set images of the sky, you probably want to use the coadd code
87 m.setMode("square") # the default; other options are "x" or "y"
89 mosaic = m.makeMosaic(im1, im2, im3) # build the mosaic
90 display = afwDisplay.getDisplay()
91 display.mtv(mosaic) # display it
92 m.drawLabels(["Label 1", "Label 2", "Label 3"], display) # label the panels
94 # alternative way to build a mosaic
95 images = [im1, im2, im3]
96 labels = ["Label 1", "Label 2", "Label 3"]
98 mosaic = m.makeMosaic(images)
100 m.drawLabels(labels, display)
102 # Yet another way to build a mosaic (no need to build the images/labels lists)
103 for i in range(len(images)):
104 m.append(images[i], labels[i])
105 # You may optionally include a colour, e.g. afwDisplay.YELLOW, as a third argument
107 mosaic = m.makeMosaic()
109 m.drawLabels(display=display)
115 mosaic = m.makeMosaic(display=display)
117 You can return the (ix, iy)th (or nth) bounding box (in pixels) with `getBBox()`
120 def __init__(self, gutter=3, background=0, mode="square"):
130 """Reset the list of images to be mosaiced"""
134 def append(self, image, label=None, ctype=None):
135 """Add an image to the list of images to be mosaiced
140 the index of this image (may be passed to `getBBox()`)
144 Set may be cleared with ``Mosaic.reset()``
146 if not self.
xsizexsize:
147 self.
xsizexsize = image.getWidth()
148 self.
ysizeysize = image.getHeight()
153 return len(self.
imagesimages)
155 def makeMosaic(self, images=None, display="deferToFrame", mode=None,
156 background=None, title=""):
157 """Return a mosaic of all the images provided.
159 If none are specified, use the list accumulated with `Mosaic.append()`.
161 If display is specified, display the mosaic
167 f
"You have already appended {len(self.images)} images to this Mosaic")
174 self.
imagesimages = images
176 images = self.
imagesimages
179 raise RuntimeError(
"You must provide at least one image")
183 w, h = im.getWidth(), im.getHeight()
184 if w > self.
xsizexsize:
186 if h > self.
ysizeysize:
189 if background
is None:
196 while nx*im.getWidth() < ny*im.getHeight():
213 elif isinstance(mode, int):
219 raise RuntimeError(f
"Unknown mosaicing mode: {mode}")
221 self.nx, self.
nyny = nx, ny
229 except AttributeError:
230 raise RuntimeError(f
"Attempt to mosaic images of type {type(mosaic)} which don't support set")
232 for i
in range(len(images)):
233 smosaic = mosaic.Factory(
234 mosaic, self.
getBBoxgetBBox(i%nx, i//nx), afwImage.LOCAL)
237 if smosaic.getDimensions() != im.getDimensions():
239 (smosaic.getHeight() - im.getHeight())//2)
241 llc, im.getDimensions()), afwImage.LOCAL)
245 display = _getDisplayFromDisplayOrFrame(display)
247 display.mtv(mosaic, title=title)
249 if images == self.
imagesimages:
255 """Set the number of pixels between panels in a mosaic
257 self.
guttergutter = gutter
260 """Set the value in the gutters
265 """Set mosaicing mode.
269 mode : {"square", "x", "y"}
273 Make mosaic as square as possible
275 Make mosaic one image high
277 Make mosaic one image wide
280 if mode
not in (
"square",
"x",
"y"):
281 raise RuntimeError(f
"Unknown mosaicing mode: {mode}")
286 """Get the BBox for a panel
291 If ``iy`` is not `None`, this is the x coordinate of the panel.
292 If ``iy`` is `None`, this is the number of the panel.
294 The y coordinate of the panel.
298 ix, iy = ix % self.nx, ix//self.nx
303 def drawLabels(self, labels=None, display="deferToFrame", frame=None):
304 """Draw the list labels at the corners of each panel.
308 If labels is None, use the ones specified by ``Mosaic.append()``
312 labels = self.
labelslabels
318 raise RuntimeError(f
"You provided {len(labels)} labels for {self.nImage} panels")
320 display = _getDisplayFromDisplayOrFrame(display, frame)
324 with display.Buffering():
325 for i
in range(len(labels)):
327 label, ctype = labels[i],
None
336 display.dot(str(label), self.
getBBoxgetBBox(i).getMinX(),
337 self.
getBBoxgetBBox(i).getMinY(), ctype=ctype)
343 return len(self.
imagesimages)
346 def drawBBox(bbox, borderWidth=0.0, origin=None, display="deferToFrame", ctype=None, bin=1, frame=None):
347 """Draw a bounding box on a display frame with the specified ctype.
351 bbox : `lsst.geom.Box2I` or `lsst.geom.Box2D`
353 borderWidth : `float`
354 Include this many pixels
356 If specified, the box is shifted by ``origin``
359 The desired color, either e.g. `lsst.afw.display.RED` or a color name known to X11
361 All BBox coordinates are divided by bin, as is right and proper for overlaying on a binned image
364 x0, y0 = bbox.getMinX(), bbox.getMinY()
365 x1, y1 = bbox.getMaxX(), bbox.getMaxY()
379 display = _getDisplayFromDisplayOrFrame(display, frame)
380 display.line([(x0 - borderWidth, y0 - borderWidth),
381 (x0 - borderWidth, y1 + borderWidth),
382 (x1 + borderWidth, y1 + borderWidth),
383 (x1 + borderWidth, y0 - borderWidth),
384 (x0 - borderWidth, y0 - borderWidth),
388 def drawFootprint(foot, borderWidth=0.5, origin=None, XY0=None, frame=None, ctype=None, bin=1,
389 peaks=False, symb="+", size=0.4, ctypePeak=None, display="deferToFrame"):
390 """Draw an `lsst.afw.detection.Footprint` on a display frame with the specified ctype.
394 foot : `lsst.afw.detection.Footprint`
395 borderWidth : `float`
396 Include an extra borderWidth pixels
398 If ``origin`` is present, it's arithmetically added to the Footprint
400 if ``XY0`` is present is subtracted from the Footprint
403 The desired color, either e.g. `lsst.afw.display.RED` or a color name known to X11
405 All Footprint coordinates are divided by bin, as is right and proper
406 for overlaying on a binned image
408 If peaks is `True`, also show the object's Peaks using the specified
409 ``symb`` and ``size`` and ``ctypePeak``
413 The desired color for peaks, either e.g. `lsst.afw.display.RED` or a color name known to X11
419 raise RuntimeError(
"You may not specify both origin and XY0")
420 origin = (-XY0[0], -XY0[1])
422 display = _getDisplayFromDisplayOrFrame(display, frame)
423 with display.Buffering():
425 for s
in foot.getSpans():
426 y, x0, x1 = s.getY(), s.getX0(), s.getX1()
437 display.line([(x0 - borderWidth, y - borderWidth),
438 (x0 - borderWidth, y + borderWidth),
439 (x1 + borderWidth, y + borderWidth),
440 (x1 + borderWidth, y - borderWidth),
441 (x0 - borderWidth, y - borderWidth),
445 for p
in foot.getPeaks():
446 x, y = p.getIx(), p.getIy()
455 display.dot(symb, x, y, size=size, ctype=ctypePeak)
459 """Draw the bounding boxes of input exposures to a coadd on a display
460 frame with the specified ctype, assuming ``display.mtv()`` has already been
461 called on the given exposure on this frame.
463 All coordinates are divided by ``bin``, as is right and proper for overlaying on a binned image
465 coaddWcs = exposure.getWcs()
466 catalog = exposure.getInfo().getCoaddInputs().ccds
470 display = _getDisplayFromDisplayOrFrame(display, frame)
472 with display.Buffering():
473 for record
in catalog:
475 ccdCorners = ccdBox.getCorners()
476 coaddCorners = [coaddWcs.skyToPixel(record.getWcs().pixelToSky(point)) + offset
477 for point
in ccdCorners]
478 display.line([(coaddCorners[i].getX()/bin, coaddCorners[i].getY()/bin)
479 for i
in range(-1, 4)], ctype=ctype)
def makeMosaic(self, images=None, display="deferToFrame", mode=None, background=None, title="")
def setGutter(self, gutter)
def getBBox(self, ix, iy=None)
def append(self, image, label=None, ctype=None)
def setBackground(self, background)
def drawLabels(self, labels=None, display="deferToFrame", frame=None)
def __init__(self, gutter=3, background=0, mode="square")
A floating-point coordinate rectangle geometry.
An integer coordinate rectangle.
def drawBBox(bbox, borderWidth=0.0, origin=None, display="deferToFrame", ctype=None, bin=1, frame=None)
def drawFootprint(foot, borderWidth=0.5, origin=None, XY0=None, frame=None, ctype=None, bin=1, peaks=False, symb="+", size=0.4, ctypePeak=None, display="deferToFrame")
def drawCoaddInputs(exposure, frame=None, ctype=None, bin=1, display="deferToFrame")
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects.