26 from __future__
import with_statement
35 """A class to handle mosaics of one or more identically-sized images (or Masks or MaskedImages)
40 m.setMode("square") # the default; other options are "x" or "y"
42 mosaic = m.makeMosaic(im1, im2, im3) # build the mosaic
43 ds9.mtv(mosaic) # display it
44 m.drawLabels(["Label 1", "Label 2", "Label 3"]) # label the panels
46 # alternative way to build a mosaic
47 images = [im1, im2, im3]
48 labels = ["Label 1", "Label 2", "Label 3"]
50 mosaic = m.makeMosaic(images)
54 # Yet another way to build a mosaic (no need to build the images/labels lists)
55 for i in range(len(images)):
56 m.append(images[i], labels[i])
57 # You may optionally include a colour, e.g. ds9.YELLOW, as a third argument
59 mosaic = m.makeMosaic()
63 You can return the (ix, iy)th (or nth) bounding box (in pixels) with getBBox()
65 def __init__(self, gutter=3, background=0, mode="square"):
75 """Reset the list of images to be mosaiced"""
79 def append(self, image, label=None, ctype=None):
80 """Add an image to the list of images to be mosaiced
81 Set may be cleared with Mosaic.reset()
83 Returns the index of this image (may be passed to getBBox())
86 self.
xsize = image.getWidth()
87 self.
ysize = image.getHeight()
89 self.images.append(image)
90 self.labels.append((label, ctype))
94 def makeMosaic(self, images=None, frame=None, mode=None, background=None, title=""):
95 """Return a mosaic of all the images provided; if none are specified,
96 use the list accumulated with Mosaic.append().
98 Note that this mosaic is a patchwork of the input images; if you want to
99 make a mosaic of a set images of the sky, you probably want to use the coadd code
101 If frame is specified, display it
109 raise RuntimeError,
"You must provide at least one image"
113 w, h = im.getWidth(), im.getHeight()
119 if background
is None:
126 while nx*im.getWidth() < ny*im.getHeight():
138 assert(nx*ny >= self.
nImage)
143 elif isinstance(mode, int):
149 raise RuntimeError, (
"Unknown mosaicing mode: %s" % mode)
151 self.nx, self.
ny = nx, ny
153 mosaic = images[0].Factory(
158 except AttributeError:
159 raise RuntimeError(
"Attempt to mosaic images of type %s which don't support set" %
162 for i
in range(len(images)):
163 smosaic = mosaic.Factory(mosaic, self.
getBBox(i%nx, i//nx), afwImage.LOCAL)
166 if smosaic.getDimensions() != im.getDimensions():
168 (smosaic.getHeight() - im.getHeight())//2)
169 smosaic = smosaic.Factory(smosaic,
afwGeom.Box2I(llc, im.getDimensions()), afwImage.LOCAL)
173 if frame
is not None:
174 ds9.mtv(mosaic, frame=frame, title=title)
182 """Set the number of pixels between panels in a mosaic"""
186 """Set the value in the gutters"""
190 """Set mosaicing mode. Valid options:
191 square Make mosaic as square as possible
192 x Make mosaic one image high
193 y Make mosaic one image wide
196 if mode
not in (
"square",
"x",
"y"):
197 raise RuntimeError, (
"Unknown mosaicing mode: %s" % mode)
202 """Get the BBox for the nth or (ix, iy)the panel"""
205 ix, iy = ix % self.nx, ix/self.nx
211 """Draw the list labels at the corners of each panel. If labels is None, use the ones
212 specified by Mosaic.append()"""
223 if len(labels) != self.
nImage:
224 raise RuntimeError, (
"You provided %d labels for %d panels" % (len(labels), self.
nImage))
227 for i
in range(len(labels)):
229 label, ctype = labels[i],
None
238 ds9.dot(str(label), self.
getBBox(i).getMinX(), self.
getBBox(i).getMinY(),
239 frame=frame, ctype=ctype)
241 def drawBBox(bbox, borderWidth=0.0, origin=None, frame=None, ctype=None, bin=1):
242 """Draw an afwImage::BBox on a ds9 frame with the specified ctype. Include an extra borderWidth pixels
243 If origin is present, it's Added to the BBox
245 All BBox coordinates are divided by bin, as is right and proper for overlaying on a binned image
247 x0, y0 = bbox.getMinX(), bbox.getMinY()
248 x1, y1 = bbox.getMaxX(), bbox.getMaxY()
251 x0 += origin[0]; x1 += origin[0]
252 y0 += origin[1]; y1 += origin[1]
258 ds9.line([(x0 - borderWidth, y0 - borderWidth),
259 (x0 - borderWidth, y1 + borderWidth),
260 (x1 + borderWidth, y1 + borderWidth),
261 (x1 + borderWidth, y0 - borderWidth),
262 (x0 - borderWidth, y0 - borderWidth),
263 ], frame=frame, ctype=ctype)
265 def drawFootprint(foot, borderWidth=0.5, origin=None, XY0=None, frame=None, ctype=None, bin=1,
266 peaks=
False, symb=
"+", size=0.4, ctypePeak=
None):
267 """Draw an afwDetection::Footprint on a ds9 frame with the specified ctype. Include an extra borderWidth
268 pixels If origin is present, it's Added to the Footprint; if XY0 is present is Subtracted from the Footprint
270 If peaks is True, also show the object's Peaks using the specified symbol and size and ctypePeak
272 All Footprint coordinates are divided by bin, as is right and proper for overlaying on a binned image
277 raise RuntimeError(
"You may not specify both origin and XY0")
278 origin = (-XY0[0], -XY0[1])
282 for s
in foot.getSpans():
283 y, x0, x1 = s.getY(), s.getX0(), s.getX1()
286 x0 += origin[0]; x1 += origin[0]
289 x0 /= bin; x1 /= bin; y /= bin
291 ds9.line([(x0 - borderWidth, y - borderWidth),
292 (x0 - borderWidth, y + borderWidth),
293 (x1 + borderWidth, y + borderWidth),
294 (x1 + borderWidth, y - borderWidth),
295 (x0 - borderWidth, y - borderWidth),
296 ], frame=frame, ctype=ctype)
299 for p
in foot.getPeaks():
300 x, y = p.getIx(), p.getIy()
303 x += origin[0]; y += origin[1]
307 ds9.dot(symb, x, y, size=size, ctype=ctypePeak, frame=frame)
310 """Draw the bounding boxes of input exposures to a coadd on a ds9 frame with the specified ctype,
311 assuming ds9.mtv() has already been called on the given exposure on this frame.
314 All coordinates are divided by bin, as is right and proper for overlaying on a binned image
316 coaddWcs = exposure.getWcs()
317 catalog = exposure.getInfo().getCoaddInputs().ccds
321 for record
in catalog:
323 ccdCorners = ccdBox.getCorners()
324 coaddCorners = [coaddWcs.skyToPixel(record.getWcs().pixelToSky(point)) + offset
325 for point
in ccdCorners]
326 ds9.line([(coaddCorners[i].getX() / bin, coaddCorners[i].getY() / bin)
327 for i
in range(-1, 4)], frame=frame, ctype=ctype)
An integer coordinate rectangle.
A floating-point coordinate rectangle geometry.