def __init__(self, config, *, display=None, **kwargs): super().__init__(config=config, **kwargs) self.makeSubtask("installPsf") self.display = None if display: self.display = display self.centroidName = "base_SdssCentroid" self.shapeName = "base_SdssShape" self.schema = afwTable.SourceTable.makeMinimalSchema() self.schema.getAliasMap().set("slot_Centroid", self.centroidName) self.schema.getAliasMap().set("slot_Shape", self.shapeName) self.control = measBase.SdssCentroidControl() self.centroider = measBase.SdssCentroidAlgorithm( self.control, self.centroidName, self.schema) self.sdssShape = measBase.SdssShapeControl() self.shaper = measBase.SdssShapeAlgorithm(self.sdssShape, self.shapeName, self.schema) self.apFluxControl = measBase.ApertureFluxControl() md = dafBase.PropertySet() self.apFluxer = measBase.CircularApertureFluxAlgorithm( self.apFluxControl, "aperFlux", self.schema, md) self.table = afwTable.SourceTable.make( self.schema) # make sure to call this last!
def showPsfMosaic(exposure, psf=None, nx=7, ny=None, showCenter=True, showEllipticity=False, showFwhm=False, stampSize=0, display=None, title=None): """Show a mosaic of Psf images. exposure may be an Exposure (optionally with PSF), or a tuple (width, height) If stampSize is > 0, the psf images will be trimmed to stampSize*stampSize """ scale = 1.0 if showFwhm: showEllipticity = True scale = 2*math.log(2) # convert sigma^2 to HWHM^2 for a Gaussian mos = displayUtils.Mosaic() try: # maybe it's a real Exposure width, height = exposure.getWidth(), exposure.getHeight() x0, y0 = exposure.getXY0() if not psf: psf = exposure.getPsf() except AttributeError: try: # OK, maybe a list [width, height] width, height = exposure[0], exposure[1] x0, y0 = 0, 0 except TypeError: # I guess not raise RuntimeError("Unable to extract width/height from object of type %s" % type(exposure)) if not ny: ny = int(nx*float(height)/width + 0.5) if not ny: ny = 1 centroidName = "SdssCentroid" shapeName = "base_SdssShape" schema = afwTable.SourceTable.makeMinimalSchema() schema.getAliasMap().set("slot_Centroid", centroidName) schema.getAliasMap().set("slot_Centroid_flag", centroidName+"_flag") control = measBase.SdssCentroidControl() centroider = measBase.SdssCentroidAlgorithm(control, centroidName, schema) sdssShape = measBase.SdssShapeControl() shaper = measBase.SdssShapeAlgorithm(sdssShape, shapeName, schema) table = afwTable.SourceTable.make(schema) table.defineCentroid(centroidName) table.defineShape(shapeName) bbox = None if stampSize > 0: w, h = psf.computeImage(lsst.geom.PointD(0, 0)).getDimensions() if stampSize <= w and stampSize <= h: bbox = lsst.geom.BoxI(lsst.geom.PointI((w - stampSize)//2, (h - stampSize)//2), lsst.geom.ExtentI(stampSize, stampSize)) centers = [] shapes = [] for iy in range(ny): for ix in range(nx): x = int(ix*(width-1)/(nx-1)) + x0 y = int(iy*(height-1)/(ny-1)) + y0 im = psf.computeImage(lsst.geom.PointD(x, y)).convertF() imPeak = psf.computePeak(lsst.geom.PointD(x, y)) im /= imPeak if bbox: im = im.Factory(im, bbox) lab = "PSF(%d,%d)" % (x, y) if False else "" mos.append(im, lab) exp = afwImage.makeExposure(afwImage.makeMaskedImage(im)) exp.setPsf(psf) w, h = im.getWidth(), im.getHeight() centerX = im.getX0() + w//2 centerY = im.getY0() + h//2 src = table.makeRecord() spans = afwGeom.SpanSet(exp.getBBox()) foot = afwDet.Footprint(spans) foot.addPeak(centerX, centerY, 1) src.setFootprint(foot) try: centroider.measure(src, exp) centers.append((src.getX() - im.getX0(), src.getY() - im.getY0())) shaper.measure(src, exp) shapes.append((src.getIxx(), src.getIxy(), src.getIyy())) except Exception: pass if not display: display = afwDisplay.Display() mos.makeMosaic(display=display, title=title if title else "Model Psf", mode=nx) if centers and display: with display.Buffering(): for i, (cen, shape) in enumerate(zip(centers, shapes)): bbox = mos.getBBox(i) xc, yc = cen[0] + bbox.getMinX(), cen[1] + bbox.getMinY() if showCenter: display.dot("+", xc, yc, ctype=afwDisplay.BLUE) if showEllipticity: ixx, ixy, iyy = shape ixx *= scale ixy *= scale iyy *= scale display.dot("@:%g,%g,%g" % (ixx, ixy, iyy), xc, yc, ctype=afwDisplay.RED) return mos
def showKernelMosaic(bbox, kernel, nx=7, ny=None, frame=None, title=None, showCenter=True, showEllipticity=True): """Show a mosaic of Kernel images. """ mos = afwDisplay.utils.Mosaic() x0 = bbox.getBeginX() y0 = bbox.getBeginY() width = bbox.getWidth() height = bbox.getHeight() if not ny: ny = int(nx*float(height)/width + 0.5) if not ny: ny = 1 schema = afwTable.SourceTable.makeMinimalSchema() centroidName = "base_SdssCentroid" shapeName = "base_SdssShape" control = measBase.SdssCentroidControl() schema.getAliasMap().set("slot_Centroid", centroidName) schema.getAliasMap().set("slot_Centroid_flag", centroidName + "_flag") centroider = measBase.SdssCentroidAlgorithm(control, centroidName, schema) sdssShape = measBase.SdssShapeControl() shaper = measBase.SdssShapeAlgorithm(sdssShape, shapeName, schema) table = afwTable.SourceTable.make(schema) table.defineCentroid(centroidName) table.defineShape(shapeName) centers = [] shapes = [] for iy in range(ny): for ix in range(nx): x = int(ix*(width - 1)/(nx - 1)) + x0 y = int(iy*(height - 1)/(ny - 1)) + y0 im = afwImage.ImageD(kernel.getDimensions()) ksum = kernel.computeImage(im, False, x, y) lab = "Kernel(%d,%d)=%.2f" % (x, y, ksum) if False else "" mos.append(im, lab) # SdssCentroidAlgorithm.measure requires an exposure of floats exp = afwImage.makeExposure(afwImage.makeMaskedImage(im.convertF())) w, h = im.getWidth(), im.getHeight() centerX = im.getX0() + w//2 centerY = im.getY0() + h//2 src = table.makeRecord() spans = afwGeom.SpanSet(exp.getBBox()) foot = afwDet.Footprint(spans) foot.addPeak(centerX, centerY, 1) src.setFootprint(foot) try: # The centroider requires a psf, so this will fail if none is attached to exp centroider.measure(src, exp) centers.append((src.getX(), src.getY())) shaper.measure(src, exp) shapes.append((src.getIxx(), src.getIxy(), src.getIyy())) except Exception: pass disp = afwDisplay.Display(frame=frame) mos.makeMosaic(display=disp, title=title if title else "Model Kernel", mode=nx) if centers and frame is not None: disp = afwDisplay.Display(frame=frame) i = 0 with disp.Buffering(): for cen, shape in zip(centers, shapes): bbox = mos.getBBox(i) i += 1 xc, yc = cen[0] + bbox.getMinX(), cen[1] + bbox.getMinY() if showCenter: disp.dot("+", xc, yc, ctype=afwDisplay.BLUE) if showEllipticity: ixx, ixy, iyy = shape disp.dot("@:%g,%g,%g" % (ixx, ixy, iyy), xc, yc, ctype=afwDisplay.RED) return mos