def showKernelSpatialCells(maskedIm, kernelCellSet, showChi2=False, symb="o", ctype=None, ctypeUnused=None, ctypeBad=None, size=3, frame=None, title="Spatial Cells"): """Show the SpatialCells. If symb is something that ds9.dot understands (e.g. "o"), the top nMaxPerCell candidates will be indicated with that symbol, using ctype and size""" ds9.mtv(maskedIm, frame=frame, title=title) with ds9.Buffering(): origin = [-maskedIm.getX0(), -maskedIm.getY0()] for cell in kernelCellSet.getCellList(): displayUtils.drawBBox(cell.getBBox(), origin=origin, frame=frame) goodies = ctypeBad is None for cand in cell.begin(goodies): xc, yc = cand.getXCenter() + origin[0], cand.getYCenter() + origin[1] if cand.getStatus() == afwMath.SpatialCellCandidate.BAD: color = ctypeBad elif cand.getStatus() == afwMath.SpatialCellCandidate.GOOD: color = ctype elif cand.getStatus() == afwMath.SpatialCellCandidate.UNKNOWN: color = ctypeUnused else: continue if color: ds9.dot(symb, xc, yc, frame=frame, ctype=color, size=size) if showChi2: rchi2 = cand.getChi2() if rchi2 > 1e100: rchi2 = np.nan ds9.dot("%d %.1f" % (cand.getId(), rchi2), xc - size, yc - size - 4, frame=frame, ctype=color, size=size)
def cosmicray(exp, config, display=False): bg = 0.0 # We background-subtracted, right? crList = measAlg.findCosmicRays(exp.getMaskedImage(), exp.getPsf(), bg, makePolicy(config), True) if crList is None: print "No CRs found" return mask = exp.getMaskedImage().getMask() crBit = mask.getPlaneBitMask("CR") afwDet.setMaskFromFootprintList(mask, crList, crBit) num = len(crList) print "Found %d CRs" % num if display: frame = 2 import lsst.afw.display.ds9 as ds9 import lsst.afw.display.utils as displayUtils ds9.mtv(exp, title="Exposure with CRs") with ds9.Buffering(): for cr in crList: displayUtils.drawBBox(cr.getBBox(), borderWidth=0.55)
def main(expName, config, display=False): exp = afwImage.ExposureF(expName) # Assume exposure is bias-subtracted, CCD-assembled, has variance and mask plane. # If not, put code here to fix what's lacking. bg, bgSubExp = estimateBackground(exp, config.background, subtract=True) detection = SourceDetectionTask(config=config.detection) detResults = detection.detectFootprints(bgSubExp, sigma=config.psfSigma) fpSet = detResults.positive print "Found %d positive footprints" % len(fpSet.getFootprints()) if display: print "Displaying results..." frame = 0 ds9.mtv(bgSubExp.getMaskedImage().getImage(), frame=frame, title="Background-subtracted exposure") with ds9.Buffering(): for fp in fpSet.getFootprints(): print "x = %s" %(fp.getBBox()) displayUtils.drawBBox(fp.getBBox(), borderWidth = 0.55) peakList = fp.getPeaks() for p in peakList: ds9.dot("x", p.getFx(), p.getFy(), frame=frame) # XXX Work with footprints here psf = measAlg.SingleGaussianPsf(config.psfSize, config.psfSize, config.psfSigma) exp.setPsf(psf) cosmicray(exp, config.cosmicray, display=display)
def showAmp(amp, imageSource=FakeImageDataSource(isTrimmed=False), frame=None, overlay=True, imageFactory=afwImage.ImageU): """!Show an amp in a ds9 frame @param[in] amp amp record to use in display @param[in] imageSource Source for getting the amp image. Must have a getAmpImage method. @param[in] frame ds9 frame to display on; defaults to frame zero @param[in] overlay Overlay bounding boxes? @param[in] imageFactory Type of image to display (only used if ampImage is None) """ ampImage = imageSource.getAmpImage(amp, imageFactory=imageFactory) ampImSize = ampImage.getDimensions() title = amp.getName() ds9.mtv(ampImage, frame=frame, title=title) if overlay: with ds9.Buffering(): if amp.getHasRawInfo() and ampImSize == amp.getRawBBox().getDimensions(): bboxes = [(amp.getRawBBox(), 0.49, ds9.GREEN),] xy0 = bboxes[0][0].getMin() bboxes.append((amp.getRawHorizontalOverscanBBox(), 0.49, ds9.RED)) bboxes.append((amp.getRawDataBBox(), 0.49, ds9.BLUE)) bboxes.append((amp.getRawPrescanBBox(), 0.49, ds9.YELLOW)) bboxes.append((amp.getRawVerticalOverscanBBox(), 0.49, ds9.MAGENTA)) else: bboxes = [(amp.getBBox(), 0.49, None),] xy0 = bboxes[0][0].getMin() for bbox, borderWidth, ctype in bboxes: if bbox.isEmpty(): continue bbox = afwGeom.Box2I(bbox) bbox.shift(-afwGeom.ExtentI(xy0)) displayUtils.drawBBox(bbox, borderWidth=borderWidth, ctype=ctype, frame=frame)
def showAmp(amp, imageSource=FakeImageDataSource(isTrimmed=False), display=None, overlay=True, imageFactory=afwImage.ImageU): """Show an amp in an image display. Parameters ---------- amp : `lsst.afw.tables.AmpInfoRecord` Amp record to use in display. imageSource : `FakeImageDataSource` or None Source for getting the amp image. Must have a ``getAmpImage()`` method. display : `lsst.afw.display.Display` Image display to use. overlay : `bool` Overlay bounding boxes? imageFactory : callable like `lsst.afw.image.Image` Type of image to display (only used if ampImage is None). """ if not display: display = _getDisplayFromDisplayOrFrame() ampImage = imageSource.getAmpImage(amp, imageFactory=imageFactory) ampImSize = ampImage.getDimensions() title = amp.getName() display.mtv(ampImage, title=title) if overlay: with display.Buffering(): if amp.getHasRawInfo() and ampImSize == amp.getRawBBox( ).getDimensions(): bboxes = [ (amp.getRawBBox(), 0.49, afwDisplay.GREEN), ] xy0 = bboxes[0][0].getMin() bboxes.append( (amp.getRawHorizontalOverscanBBox(), 0.49, afwDisplay.RED)) bboxes.append((amp.getRawDataBBox(), 0.49, afwDisplay.BLUE)) bboxes.append( (amp.getRawPrescanBBox(), 0.49, afwDisplay.YELLOW)) bboxes.append((amp.getRawVerticalOverscanBBox(), 0.49, afwDisplay.MAGENTA)) else: bboxes = [ (amp.getBBox(), 0.49, None), ] xy0 = bboxes[0][0].getMin() for bbox, borderWidth, ctype in bboxes: if bbox.isEmpty(): continue bbox = lsst.geom.Box2I(bbox) bbox.shift(-lsst.geom.ExtentI(xy0)) displayUtils.drawBBox(bbox, borderWidth=borderWidth, ctype=ctype, display=display)
def DrawStat(stat, zoom_to_point = False): # if stat.ellipse_b == 0: # ds9.zoom(22, stat.centroid_x,stat.centroid_y, 0) # use to zoom to a single point argstring = "@:"+str(4*stat.ellipse_Ixx)+','+str(4*stat.ellipse_Ixy)+','+str(4*stat.ellipse_Iyy) #multiply by four just to make it more exaggerated otherwise they all look like cirlces ds9.dot(argstring,stat.centroid_x,stat.centroid_y) #ellipse around the centroid ds9.dot("x",stat.centroid_x,stat.centroid_y)# cross on the peak displayUtils.drawBBox(stat.BBox, borderWidth=0.5) # border to fully encompass the bbox and no more if zoom_to_point: ds9.zoom(22, stat.centroid_x,stat.centroid_y, 0) # use to zoom to a single point print 'length (diag,px) = %s, length (3D,true,um) = %s, flux = %s, npix = %s, dedx = %s' %(stat.diagonal_length_pixels, stat.length_true_um, stat.flux, stat.npix, stat.de_dx)
def cosmicRay(self, exposure, keepCRs=None): """Mask cosmic rays \param[in,out] exposure Exposure to process \param[in] keepCRs Don't interpolate over the CR pixels (defer to pex_config if None) """ import lsstDebug display = lsstDebug.Info(__name__).display displayCR = lsstDebug.Info(__name__).displayCR assert exposure, "No exposure provided" psf = exposure.getPsf() assert psf, "No psf provided" # Blow away old mask try: mask = exposure.getMaskedImage().getMask() crBit = mask.getMaskPlane("CR") mask.clearMaskPlane(crBit) except Exception: pass mi = exposure.getMaskedImage() bg = afwMath.makeStatistics(mi, afwMath.MEDIAN).getValue() if keepCRs is None: keepCRs = self.config.cosmicray.keepCRs try: crs = measAlg.findCosmicRays(mi, psf, bg, pexConfig.makePolicy(self.config.cosmicray), keepCRs) except Exception: if display: import lsst.afw.display.ds9 as ds9 ds9.mtv(exposure, title="Failed CR") raise num = 0 if crs is not None: mask = mi.getMask() crBit = mask.getPlaneBitMask("CR") afwDet.setMaskFromFootprintList(mask, crs, crBit) num = len(crs) if display and displayCR: import lsst.afw.display.ds9 as ds9 import lsst.afw.display.utils as displayUtils ds9.incrDefaultFrame() ds9.mtv(exposure, title="Post-CR") with ds9.Buffering(): for cr in crs: displayUtils.drawBBox(cr.getBBox(), borderWidth=0.55) self.log.info("Identified %s cosmic rays." % (num,))
def showPsfSpatialCells(exposure, psfCellSet, nMaxPerCell=-1, showChi2=False, showMoments=False, symb=None, ctype=None, ctypeUnused=None, ctypeBad=None, size=2, display=None): """Show the SpatialCells. If symb is something that afwDisplay.Display.dot() understands (e.g. "o"), the top nMaxPerCell candidates will be indicated with that symbol, using ctype and size. """ if not display: display = afwDisplay.Display() with display.Buffering(): origin = [-exposure.getMaskedImage().getX0(), -exposure.getMaskedImage().getY0()] for cell in psfCellSet.getCellList(): displayUtils.drawBBox(cell.getBBox(), origin=origin, display=display) if nMaxPerCell < 0: nMaxPerCell = 0 i = 0 goodies = ctypeBad is None for cand in cell.begin(goodies): if nMaxPerCell > 0: i += 1 xc, yc = cand.getXCenter() + origin[0], cand.getYCenter() + origin[1] if i > nMaxPerCell: if not ctypeUnused: continue color = ctypeBad if cand.isBad() else ctype if symb: if i > nMaxPerCell: ct = ctypeUnused else: ct = ctype display.dot(symb, xc, yc, ctype=ct, size=size) source = cand.getSource() if showChi2: rchi2 = cand.getChi2() if rchi2 > 1e100: rchi2 = numpy.nan display.dot("%d %.1f" % (splitId(source.getId(), True)["objId"], rchi2), xc - size, yc - size - 4, ctype=color, size=2) if showMoments: display.dot("%.2f %.2f %.2f" % (source.getIxx(), source.getIxy(), source.getIyy()), xc-size, yc + size + 4, ctype=color, size=size) return display
def testDefectBase(self): """Test DefectBases""" #print >> sys.stderr, "Skipping testDefectBase"; return defectsDict = cameraGeomUtils.makeDefects(self.geomPolicy) for ccdName in ("Defective", "Defective II"): ccd = cameraGeomUtils.makeCcd(self.geomPolicy, cameraGeom.Id(ccdName)) ccdImage = cameraGeomUtils.makeImageFromCcd(ccd) if ccdName == "Defective": # # Insert some defects into the Ccd # for x0, y0, x1, y1 in [ (34, 0, 35, 80 ), (34, 81, 34, 100), (180, 100, 182, 130), ]: bbox = afwGeom.Box2I(afwGeom.Point2I(x0, y0), afwGeom.Point2I(x1, y1)) bad = ccdImage.Factory(ccdImage, bbox, afwImage.LOCAL) bad.set(100) if display: ds9.mtv(ccdImage, title="Defects") cameraGeomUtils.showCcd(ccd, None) defects = [v for (k, v) in defectsDict.items() if k == ccd.getId()] if len(defects) == 0: contine elif len(defects) == 1: defects = defects[0] else: raise RuntimeError, ("Found more than one defect set for CCD %s" % ccd.getId()) ccd.setDefects(defects) if False: print "CCD (%s)" % ccd.getId() for a in ccd: print " ", a.getId(), [str(d.getBBox()) for d in a.getDefects()] if ccdName == "Defective" and display: for d in ccd.getDefects(): displayUtils.drawBBox(d.getBBox(), ctype=ds9.CYAN, borderWidth=1.5) for a in ccd: for d in a.getDefects(): displayUtils.drawBBox(d.getBBox(), ctype=ds9.YELLOW, borderWidth=1.0) ds9.incrDefaultFrame()
def DrawStatFromScratch(stat, bgsubtract): metadata_filename = '/home/mmmerlin/useful/herring_bone.fits' image = AssembleImage(stat.filename, metadata_filename, bgsubtract) print "track at %s,%s in %s"%(stat.centroid_x,stat.centroid_y,stat.filename) ds9.mtv(image) # exit() argstring = "@:"+str(4*stat.ellipse_Ixx)+','+str(4*stat.ellipse_Ixy)+','+str(4*stat.ellipse_Iyy) #multiply by four just to make it more exaggerated otherwise they all look like cirlces ds9.dot(argstring,stat.centroid_x,stat.centroid_y) #ellipse around the centroid ds9.dot("x",stat.centroid_x,stat.centroid_y)# cross on the peak displayUtils.drawBBox(stat.BBox, borderWidth=0.5) # border to fully encompass the bbox and no more ds9.zoom(22, stat.centroid_x,stat.centroid_y, 0) # use to zoom to a single point
def DEBUG(image, footprintset): ds9.mtv(image) for footprint in footprintset: from lsst.afw.image.imageLib import MaskedImageF masked_imaged = MaskedImageF(image) heavy_footprint = afwDetect.HeavyFootprintF(footprint, masked_imaged) stat = GetTrackStats(heavy_footprint, image, False) argstring = "@:"+str(4*stat.ellipse_Ixx)+','+str(4*stat.ellipse_Ixy)+','+str(4*stat.ellipse_Iyy) #multiply by four just to make it more exaggerated otherwise they all look like cirlces ds9.dot(argstring,stat.centroid_x,stat.centroid_y) #ellipse around the centroid ds9.dot("x",stat.centroid_x,stat.centroid_y)# cross on the peak displayUtils.drawBBox(stat.BBox, borderWidth=0.5) # border to fully encompass the bbox and no more
def showAmp(amp, imageSource=FakeImageDataSource(isTrimmed=False), display=None, overlay=True, imageFactory=afwImage.ImageU): """!Show an amp in an image display @param[in] amp amp record to use in display @param[in] imageSource Source for getting the amp image. Must have a getAmpImage method. @param[in] display image display to use @param[in] overlay Overlay bounding boxes? @param[in] imageFactory Type of image to display (only used if ampImage is None) """ if not display: display = _getDisplayFromDisplayOrFrame() ampImage = imageSource.getAmpImage(amp, imageFactory=imageFactory) ampImSize = ampImage.getDimensions() title = amp.getName() display.mtv(ampImage, title=title) if overlay: with display.Buffering(): if amp.getHasRawInfo() and ampImSize == amp.getRawBBox( ).getDimensions(): bboxes = [ (amp.getRawBBox(), 0.49, afwDisplay.GREEN), ] xy0 = bboxes[0][0].getMin() bboxes.append( (amp.getRawHorizontalOverscanBBox(), 0.49, afwDisplay.RED)) bboxes.append((amp.getRawDataBBox(), 0.49, afwDisplay.BLUE)) bboxes.append( (amp.getRawPrescanBBox(), 0.49, afwDisplay.YELLOW)) bboxes.append((amp.getRawVerticalOverscanBBox(), 0.49, afwDisplay.MAGENTA)) else: bboxes = [ (amp.getBBox(), 0.49, None), ] xy0 = bboxes[0][0].getMin() for bbox, borderWidth, ctype in bboxes: if bbox.isEmpty(): continue bbox = afwGeom.Box2I(bbox) bbox.shift(-afwGeom.ExtentI(xy0)) displayUtils.drawBBox(bbox, borderWidth=borderWidth, ctype=ctype, display=display)
def testDefectBase(self): """Test DefectBases""" defectList = [] ccdImage = afwImage.MaskedImageF(250, 225) ccdImage.set(self.setVal, 0, self.setVal) # # Insert some defects into the Ccd # for x0, y0, x1, y1 in [ (34, 0, 35, 80), (34, 81, 34, 100), (180, 100, 182, 130), ]: bbox = afwGeom.Box2I(afwGeom.Point2I(x0, y0), afwGeom.Point2I(x1, y1)) defectList.append(measAlg.Defect(bbox)) bad = ccdImage.Factory(ccdImage, bbox, afwImage.LOCAL) bad.set(100) ipIsr.maskPixelsFromDefectList(ccdImage, defectList, maskName='BAD') mask = ccdImage.getMask() bitMask = mask.getPlaneBitMask('BAD') for d in defectList: bad = mask.Factory(mask, d.getBBox(), afwImage.LOCAL) self.assertTrue((bad.getArray() & bitMask == bitMask).all()) if display: ds9.mtv(ccdImage.getImage(), title="Defects") for d in defectList: displayUtils.drawBBox(d.getBBox(), ctype=ds9.CYAN, borderWidth=.5) ds9.incrDefaultFrame() ipIsr.interpolateDefectList(ccdImage, defectList, 2.) im = ccdImage.getImage() for d in defectList: intrp = im.Factory(im, d.getBBox()) expect = np.empty_like(intrp.getArray()) expect[:] = self.setVal self.assertImagesEqual(intrp, expect) if display: ds9.mtv(ccdImage.getImage(), title="Defects Interpolated") for d in defectList: displayUtils.drawBBox(d.getBBox(), ctype=ds9.CYAN, borderWidth=.5) ds9.incrDefaultFrame()
def cosmicray(self, exposure, psf): """Cosmic ray masking @param exposure Exposure to process @param psf PSF """ import lsstDebug display = lsstDebug.Info(__name__).display displayCR = lsstDebug.Info(__name__).displayCR assert exposure, "No exposure provided" assert psf, "No psf provided" # Blow away old mask try: mask = exposure.getMaskedImage().getMask() crBit = mask.getMaskPlane("CR") mask.clearMaskPlane(crBit) except: pass if display and displayCR: ds9.incrDefaultFrame() ds9.mtv(exposure, title="Pre-CR") policy = self.config['cosmicray'].getPolicy() mi = exposure.getMaskedImage() bg = afwMath.makeStatistics(mi, afwMath.MEDIAN).getValue() crs = measAlg.findCosmicRays(mi, psf, bg, policy, self._keepCRs) num = 0 if crs is not None: mask = mi.getMask() crBit = mask.getPlaneBitMask("CR") afwDet.setMaskFromFootprintList(mask, crs, crBit) num = len(crs) if display and displayCR: ds9.incrDefaultFrame() ds9.mtv(exposure, title="Post-CR") ds9.cmdBuffer.pushSize() for cr in crs: displayUtils.drawBBox(cr.getBBox(), borderWidth=0.55) ds9.cmdBuffer.popSize() self.log.log(self.log.INFO, "Identified %d cosmic rays." % num) return
def showAmp(amp, imageSource=FakeImageDataSource(isTrimmed=False), display=None, overlay=True, imageFactory=afwImage.ImageU): """Show an amp in an image display. Parameters ---------- amp : `lsst.afw.tables.AmpInfoRecord` Amp record to use in display. imageSource : `FakeImageDataSource` or `None` Source for getting the amp image. Must have a ``getAmpImage()`` method. display : `lsst.afw.display.Display` Image display to use. overlay : `bool` Overlay bounding boxes? imageFactory : callable like `lsst.afw.image.Image` Type of image to display (only used if ampImage is `None`). """ if not display: display = _getDisplayFromDisplayOrFrame(display) ampImage = imageSource.getAmpImage(amp, imageFactory=imageFactory) ampImSize = ampImage.getDimensions() title = amp.getName() display.mtv(ampImage, title=title) if overlay: with display.Buffering(): if amp.getHasRawInfo() and ampImSize == amp.getRawBBox().getDimensions(): bboxes = [(amp.getRawBBox(), 0.49, afwDisplay.GREEN), ] xy0 = bboxes[0][0].getMin() bboxes.append( (amp.getRawHorizontalOverscanBBox(), 0.49, afwDisplay.RED)) bboxes.append((amp.getRawDataBBox(), 0.49, afwDisplay.BLUE)) bboxes.append((amp.getRawPrescanBBox(), 0.49, afwDisplay.YELLOW)) bboxes.append((amp.getRawVerticalOverscanBBox(), 0.49, afwDisplay.MAGENTA)) else: bboxes = [(amp.getBBox(), 0.49, None), ] xy0 = bboxes[0][0].getMin() for bbox, borderWidth, ctype in bboxes: if bbox.isEmpty(): continue bbox = lsst.geom.Box2I(bbox) bbox.shift(-lsst.geom.ExtentI(xy0)) displayUtils.drawBBox( bbox, borderWidth=borderWidth, ctype=ctype, display=display)
def testDefectBase(self): """Test DefectBases""" defectList = measAlg.DefectListT() ccdImage = afwImage.MaskedImageF(250,225) ccdImage.set(self.setVal, 0, self.setVal) # # Insert some defects into the Ccd # for x0, y0, x1, y1 in [ (34, 0, 35, 80 ), (34, 81, 34, 100), (180, 100, 182, 130), ]: bbox = afwGeom.Box2I(afwGeom.Point2I(x0, y0), afwGeom.Point2I(x1, y1)) defectList.append(measAlg.Defect(bbox)) bad = ccdImage.Factory(ccdImage, bbox, afwImage.LOCAL) bad.set(100) ipIsr.maskPixelsFromDefectList(ccdImage, defectList, maskName='BAD') mask = ccdImage.getMask() bitMask = mask.getPlaneBitMask('BAD') for d in defectList: bad = mask.Factory(mask, d.getBBox(), afwImage.LOCAL) self.assertTrue((bad.getArray()&bitMask == bitMask).all()) if display: ds9.mtv(ccdImage.getImage(), title="Defects") for d in defectList: displayUtils.drawBBox(d.getBBox(), ctype=ds9.CYAN, borderWidth=.5) ds9.incrDefaultFrame() ipIsr.interpolateDefectList(ccdImage, defectList, 2.) im = ccdImage.getImage() for d in defectList: intrp = im.Factory(im, d.getBBox()) self.assertTrue((intrp.getArray() == self.setVal).all()) if display: ds9.mtv(ccdImage.getImage(), title="Defects Interpolated") for d in defectList: displayUtils.drawBBox(d.getBBox(), ctype=ds9.CYAN, borderWidth=.5) ds9.incrDefaultFrame()
def showCamera(camera, imageSource=FakeImageDataSource(), imageFactory=afwImage.ImageF, detectorNameList=None, binSize=10, bufferSize=10, frame=None, overlay=True, title="", showWcs=None, ctype=afwDisplay.GREEN, textSize=1.25, originAtCenter=True, display=None, **kwargs): """Show a Camera on display, with the specified display. The rotation of the sensors is snapped to the nearest multiple of 90 deg. Also note that the pixel size is constant over the image array. The lower left corner (LLC) of each sensor amp is snapped to the LLC of the pixel containing the LLC of the image. Parameters ---------- camera : `lsst.afw.cameraGeom.Camera` Camera object to use to make the image. imageSource : `FakeImageDataSource` or None Source to get ccd images. Must have a ``getCcdImage()`` method. imageFactory : `lsst.afw.image.Image` Type of image to make detectorNameList : `list` of `str` List of detector names from `camera` to use in building the image. Use all Detectors if None. binSize : `int` Bin the image by this factor in both dimensions. bufferSize : `int` Size of border in binned pixels to make around the camera image. frame : None specify image display. **Deprecated** in v12. overlay : `bool` Overlay Detector IDs and boundaries? title : `str` Title to use in display. showWcs : `bool` Include a WCS in the display? ctype : `lsst.afw.display.COLOR` or `str` Color to use when drawing Detector boundaries. textSize : `float` Size of detector labels originAtCenter : `bool` Put origin of the camera WCS at the center of the image? If False, the origin will be at the lower left. display : `lsst.afw.display` Image display on which to display. **kwargs : All remaining keyword arguments are passed to makeImageFromCamera Returns ------- image : `lsst.afw.image.Image` The mosaic image. """ if frame is not None: warnings.warn( "The frame kwarg is deprecated; use the `lsst.afw.display` system instead.", DeprecationWarning) display = _getDisplayFromDisplayOrFrame(display, frame) if binSize < 1: binSize = 1 cameraImage = makeImageFromCamera(camera, detectorNameList=detectorNameList, bufferSize=bufferSize, imageSource=imageSource, imageFactory=imageFactory, binSize=binSize, **kwargs) if detectorNameList is None: ccdList = [camera[name] for name in camera.getNameIter()] else: ccdList = [camera[name] for name in detectorNameList] if detectorNameList is None: camBbox = camera.getFpBBox() else: camBbox = lsst.geom.Box2D() for detName in detectorNameList: for corner in camera[detName].getCorners(FOCAL_PLANE): camBbox.include(corner) pixelSize = ccdList[0].getPixelSize() if showWcs: if originAtCenter: wcsReferencePixel = lsst.geom.Box2D( cameraImage.getBBox()).getCenter() else: wcsReferencePixel = lsst.geom.Point2I(0, 0) wcs = makeFocalPlaneWcs(pixelSize * binSize, wcsReferencePixel) else: wcs = None if display: if title == "": title = camera.getName() display.mtv(cameraImage, title=title, wcs=wcs) if overlay: with display.Buffering(): camBbox = getCameraImageBBox(camBbox, pixelSize, bufferSize * binSize) bboxList = getCcdInCamBBoxList(ccdList, binSize, pixelSize, camBbox.getMin()) for bbox, ccd in zip(bboxList, ccdList): nQuarter = ccd.getOrientation().getNQuarter() # borderWidth to 0.5 to align with the outside edge of the # pixel displayUtils.drawBBox(bbox, borderWidth=0.5, ctype=ctype, display=display) dims = bbox.getDimensions() display.dot(ccd.getName(), bbox.getMinX() + dims.getX() / 2, bbox.getMinY() + dims.getY() / 2, ctype=ctype, size=textSize, textAngle=nQuarter * 90) return cameraImage
def showCamera(camera, imageSource=FakeImageDataSource(), imageFactory=afwImage.ImageF, detectorNameList=None, binSize=10, bufferSize=10, frame=None, overlay=True, title="", showWcs=None, ctype=afwDisplay.GREEN, textSize=1.25, originAtCenter=True, display=None, **kwargs): """Show a Camera on display, with the specified display. The rotation of the sensors is snapped to the nearest multiple of 90 deg. Also note that the pixel size is constant over the image array. The lower left corner (LLC) of each sensor amp is snapped to the LLC of the pixel containing the LLC of the image. Parameters ---------- camera : `lsst.afw.cameraGeom.Camera` Camera object to use to make the image. imageSource : `FakeImageDataSource` or `None` Source to get ccd images. Must have a ``getCcdImage()`` method. imageFactory : `lsst.afw.image.Image` Type of image to make detectorNameList : `list` of `str` or `None` List of detector names from `camera` to use in building the image. Use all Detectors if `None`. binSize : `int` Bin the image by this factor in both dimensions. bufferSize : `int` Size of border in binned pixels to make around the camera image. frame : `None` specify image display. **Deprecated** in v12. overlay : `bool` Overlay Detector IDs and boundaries? title : `str` Title to use in display. showWcs : `bool` Include a WCS in the display? ctype : `lsst.afw.display.COLOR` or `str` Color to use when drawing Detector boundaries. textSize : `float` Size of detector labels originAtCenter : `bool` Put origin of the camera WCS at the center of the image? If `False`, the origin will be at the lower left. display : `lsst.afw.display` Image display on which to display. **kwargs : All remaining keyword arguments are passed to makeImageFromCamera Returns ------- image : `lsst.afw.image.Image` The mosaic image. """ if frame is not None: warnings.warn("The frame kwarg is deprecated; use the `lsst.afw.display` system instead.", DeprecationWarning) display = _getDisplayFromDisplayOrFrame(display, frame) if binSize < 1: binSize = 1 cameraImage = makeImageFromCamera(camera, detectorNameList=detectorNameList, bufferSize=bufferSize, imageSource=imageSource, imageFactory=imageFactory, binSize=binSize, **kwargs) if detectorNameList is None: ccdList = [camera[name] for name in camera.getNameIter()] else: ccdList = [camera[name] for name in detectorNameList] if detectorNameList is None: camBbox = camera.getFpBBox() else: camBbox = lsst.geom.Box2D() for detName in detectorNameList: for corner in camera[detName].getCorners(FOCAL_PLANE): camBbox.include(corner) pixelSize = ccdList[0].getPixelSize() if showWcs: if originAtCenter: wcsReferencePixel = lsst.geom.Box2D( cameraImage.getBBox()).getCenter() else: wcsReferencePixel = lsst.geom.Point2I(0, 0) wcs = makeFocalPlaneWcs(pixelSize*binSize, wcsReferencePixel) else: wcs = None if display: if title == "": title = camera.getName() display.mtv(cameraImage, title=title, wcs=wcs) if overlay: with display.Buffering(): camBbox = getCameraImageBBox( camBbox, pixelSize, bufferSize*binSize) bboxList = getCcdInCamBBoxList( ccdList, binSize, pixelSize, camBbox.getMin()) for bbox, ccd in zip(bboxList, ccdList): nQuarter = ccd.getOrientation().getNQuarter() # borderWidth to 0.5 to align with the outside edge of the # pixel displayUtils.drawBBox( bbox, borderWidth=0.5, ctype=ctype, display=display) dims = bbox.getDimensions() display.dot(ccd.getName(), bbox.getMinX() + dims.getX()/2, bbox.getMinY() + dims.getY()/2, ctype=ctype, size=textSize, textAngle=nQuarter*90) return cameraImage
def fitPatches(exp, nx=4, ny=8, bin=None, frame=None, returnResidualImage=False, r=None, lnGrad=None, theta=None): """Fit planes to a set of patches of an image im If r, theta, and lnGrad are provided they should be lists (more accurately, support .append), and they have the values of r, theta, and dlnI/dr from this image appended. """ width, height = exp.getDimensions() if bin is not None: nx, ny = width // bin, height // bin xsize = width // nx ysize = height // ny if frame is not None: frame0 = frame ds9.mtv(exp, title="im", frame=frame) if True else None frame += 1 if hasattr(exp, "getMaskedImage"): mi = exp.getMaskedImage() ccd = exp.getDetector() else: mi = exp ccd = None try: mi = mi.convertF() except AttributeError: pass if r is not None or lnGrad is not None: assert ccd is not None, "I need a CCD to set r and the logarithmic gradient" assert r is not None and lnGrad is not None, "Please provide both r and lnGrad" z = afwImage.ImageF(nx, ny) za = z.getArray() dlnzdx = afwImage.ImageF(nx, ny) dlnzdxa = dlnzdx.getArray() dlnzdy = afwImage.ImageF(nx, ny) dlnzdya = dlnzdy.getArray() dlnzdr = afwImage.ImageF(nx, ny) dlnzdra = dlnzdr.getArray() if returnResidualImage: residualImage = mi.clone() try: residualImage = residualImage.convertF() except AttributeError: pass else: residualImage = None with ds9.Buffering(): for iy in range(ny): for ix in range(nx): bbox = afwGeom.BoxI(afwGeom.PointI(ix * xsize, iy * ysize), afwGeom.ExtentI(xsize, ysize)) if False and frame is not None: ds9Utils.drawBBox(bbox, frame=frame0) b, res = fitPlane(mi[bbox].getImage(), returnResidualImage=returnResidualImage, niter=5) b[1:] /= b[0] za[iy, ix], dlnzdxa[iy, ix], dlnzdya[iy, ix] = b if returnResidualImage: residualImage[bbox][:] = res if ccd: cen = afwGeom.PointD(bbox.getBegin() + bbox.getDimensions() / 2) x, y = ccd.getPositionFromPixel( cen).getMm() # I really want pixels here t = np.arctan2(y, x) dlnzdra[iy, ix] = np.cos(t) * dlnzdxa[iy, ix] + np.sin( t) * dlnzdya[iy, ix] if r is not None: if not (ix in (0, xsize - 1) or iy in (0, ysize - 1)): r.append(np.hypot(x, y)) lnGrad.append(dlnzdra[iy, ix]) if theta is not None: theta.append(t) if frame is not None: if False: ds9.mtv(z, title="z", frame=frame) frame += 1 ds9.mtv(dlnzdx, title="dlnz/dx", frame=frame) frame += 1 ds9.mtv(dlnzdy, title="dlnz/dy", frame=frame) frame += 1 ds9.mtv(residualImage, title="res", frame=frame) frame += 1 ds9.mtv(dlnzdr, title="dlnz/dr %s" % (ccd.getId().getSerial() if ccd else ""), frame=frame) frame += 1 return dlnzdx, dlnzdy, dlnzdr, residualImage
footPrintSet = afwDetect.FootprintSet(image, threshold, npixMin) footPrintSet = afwDetect.FootprintSet(footPrintSet, grow, isotropic) footPrints = footPrintSet.getFootprints() dt = time.time() - t0 print "Source finding took %.2f us" %(dt*1e6) print "Found %s footprints in %s"%(len(footPrints), filename) t_total += dt t0 = time.time() centroids = [] for footprintnum, footprint in enumerate(footPrints): centroids.append([footprint.getCentroid()]) centroid_x, centroid_y = footprint.getCentroid() ds9.dot("x",centroid_x,centroid_y)# cross on the peak displayUtils.drawBBox(footprint.getBBox(), borderWidth=0.5) # border to fully encompass the bbox and no more dt = time.time() - t0 print "Centroid listing took %.2f us" %(dt*1e6) print "Total time was %.2f us" %(t_total*1e6) print '\n***End code***'
def showCamera(camera, imageSource=FakeImageDataSource(), imageFactory=afwImage.ImageF, detectorNameList=None, binSize=10, bufferSize=10, frame=None, overlay=True, title="", ctype=afwDisplay.GREEN, textSize=1.25, originAtCenter=True, display=None, **kwargs): """!Show a Camera on display, with the specified display The rotation of the sensors is snapped to the nearest multiple of 90 deg. Also note that the pixel size is constant over the image array. The lower left corner (LLC) of each sensor amp is snapped to the LLC of the pixel containing the LLC of the image. if overlay show the IDs and detector boundaries @param[in] camera Camera to show @param[in] imageSource Source to get Ccd images from. Must have a getCcdImage method. @param[in] imageFactory Type of image to make @param[in] detectorNameList List of names of Detectors to use. If None use all @param[in] binSize bin factor @param[in] bufferSize size of border in binned pixels to make around camera image. @param[in] frame specify image display (@deprecated; new code should use display) @param[in] overlay Overlay Detector IDs and boundaries? @param[in] title Title in display @param[in] ctype Color to use when drawing Detector boundaries @param[in] textSize Size of detector labels @param[in] originAtCenter Put origin of the camera WCS at the center of the image? Else it will be LL @param[in] display image display on which to display @param[in] **kwargs all remaining keyword arguments are passed to makeImageFromCamera @return the mosaic image """ display = _getDisplayFromDisplayOrFrame(display, frame) if binSize < 1: binSize = 1 cameraImage = makeImageFromCamera(camera, detectorNameList=detectorNameList, bufferSize=bufferSize, imageSource=imageSource, imageFactory=imageFactory, binSize=binSize, **kwargs) if detectorNameList is None: ccdList = [camera[name] for name in camera.getNameIter()] else: ccdList = [camera[name] for name in detectorNameList] if detectorNameList is None: camBbox = camera.getFpBBox() else: camBbox = afwGeom.Box2D() for detName in detectorNameList: for corner in camera[detName].getCorners(FOCAL_PLANE): camBbox.include(corner) pixelSize = ccdList[0].getPixelSize() if originAtCenter: #Can't divide SWIGGED extent type things when division is imported #from future. This is DM-83 ext = cameraImage.getBBox().getDimensions() wcsReferencePixel = afwGeom.PointI(ext.getX() // 2, ext.getY() // 2) else: wcsReferencePixel = afwGeom.Point2I(0, 0) wcs = makeFocalPlaneWcs(pixelSize * binSize, wcsReferencePixel) if display: if title == "": title = camera.getName() display.mtv(cameraImage, title=title, wcs=wcs) if overlay: with display.Buffering(): camBbox = getCameraImageBBox(camBbox, pixelSize, bufferSize * binSize) bboxList = getCcdInCamBBoxList(ccdList, binSize, pixelSize, camBbox.getMin()) for bbox, ccd in zip(bboxList, ccdList): nQuarter = ccd.getOrientation().getNQuarter() # borderWidth to 0.5 to align with the outside edge of the pixel displayUtils.drawBBox(bbox, borderWidth=0.5, ctype=ctype, display=display) dims = bbox.getDimensions() display.dot(ccd.getName(), bbox.getMinX() + dims.getX() / 2, bbox.getMinY() + dims.getY() / 2, ctype=ctype, size=textSize, textAngle=nQuarter * 90) return cameraImage
def cosmicRay(self, exposure, keepCRs=None): """Mask cosmic rays \param[in,out] exposure Exposure to process \param[in] keepCRs Don't interpolate over the CR pixels (defer to pex_config if None) """ import lsstDebug display = lsstDebug.Info(__name__).display displayCR = lsstDebug.Info(__name__).displayCR assert exposure, "No exposure provided" psf = exposure.getPsf() assert psf, "No psf provided" # Blow away old mask try: mask = exposure.getMaskedImage().getMask() crBit = mask.getMaskPlane("CR") mask.clearMaskPlane(crBit) except Exception: pass exposure0 = exposure # initial value of exposure binSize = self.config.cosmicray.background.binSize nx, ny = exposure.getWidth() / binSize, exposure.getHeight() / binSize # Treat constant background as a special case to avoid the extra complexity in calling # measAlg.SubtractBackgroundTask(). if nx * ny <= 1: medianBg = afwMath.makeStatistics(exposure.getMaskedImage(), afwMath.MEDIAN).getValue() modelBg = None else: # make a deep copy of the exposure before subtracting its background, # because this routine is only allowed to modify the exposure by setting mask planes # and interpolating over defects, not changing the background level exposure = exposure.Factory(exposure, True) subtractBackgroundTask = measAlg.SubtractBackgroundTask( config=self.config.cosmicray.background) modelBg = subtractBackgroundTask.run(exposure).background medianBg = 0.0 if keepCRs is None: keepCRs = self.config.cosmicray.keepCRs try: crs = measAlg.findCosmicRays( exposure.getMaskedImage(), psf, medianBg, pexConfig.makePolicy(self.config.cosmicray), keepCRs) if modelBg: # Add back background image img = exposure.getMaskedImage() img += modelBg.getImageF() del img # Replace original image with CR subtracted image exposure0.setMaskedImage(exposure.getMaskedImage()) except Exception: if display: import lsst.afw.display.ds9 as ds9 ds9.mtv(exposure0, title="Failed CR") raise num = 0 if crs is not None: mask = exposure0.getMaskedImage().getMask() crBit = mask.getPlaneBitMask("CR") afwDet.setMaskFromFootprintList(mask, crs, crBit) num = len(crs) if display and displayCR: import lsst.afw.display.ds9 as ds9 import lsst.afw.display.utils as displayUtils ds9.incrDefaultFrame() ds9.mtv(exposure0, title="Post-CR") with ds9.Buffering(): for cr in crs: displayUtils.drawBBox(cr.getBBox(), borderWidth=0.55) self.log.info("Identified %s cosmic rays." % (num, ))
def overlayCcdBoxes(ccd, untrimmedCcdBbox, nQuarter, isTrimmed, ccdOrigin, display, binSize): """!Overlay bounding boxes on an image display @param[in] ccd Detector to iterate for the amp bounding boxes @param[in] untrimmedCcdBbox Bounding box of the un-trimmed Detector @param[in] nQuarter number of 90 degree rotations to apply to the bounding boxes @param[in] isTrimmed Is the Detector image over which the boxes are layed trimmed? @param[in] ccdOrigin Detector origin relative to the parent origin if in a larger pixel grid @param[in] display image display to display on @param[in] binSize binning factor """ with display.Buffering(): ccdDim = untrimmedCcdBbox.getDimensions() ccdBbox = rotateBBoxBy90(untrimmedCcdBbox, nQuarter, ccdDim) for amp in ccd: if isTrimmed: ampbbox = amp.getBBox() else: ampbbox = amp.getRawBBox() ampbbox.shift(amp.getRawXYOffset()) if nQuarter != 0: ampbbox = rotateBBoxBy90(ampbbox, nQuarter, ccdDim) displayUtils.drawBBox(ampbbox, origin=ccdOrigin, borderWidth=0.49, display=display, bin=binSize) if not isTrimmed and amp.getHasRawInfo(): for bbox, ctype in ((amp.getRawHorizontalOverscanBBox(), afwDisplay.RED), (amp.getRawDataBBox(), afwDisplay.BLUE), (amp.getRawVerticalOverscanBBox(), afwDisplay.MAGENTA), (amp.getRawPrescanBBox(), afwDisplay.YELLOW)): if amp.getRawFlipX(): x0 = bbox.getBeginX() bbox.flipLR(amp.getRawBBox().getDimensions().getX()) bbox.shift(afwGeom.ExtentI(x0 - bbox.getBeginX(), 0)) if amp.getRawFlipY(): y0 = bbox.getBeginY() bbox.flipTB(amp.getRawBBox().getDimensions().getY()) bbox.shift(afwGeom.ExtentI(0, y0 - bbox.getBeginY())) bbox.shift(amp.getRawXYOffset()) if nQuarter != 0: bbox = rotateBBoxBy90(bbox, nQuarter, ccdDim) displayUtils.drawBBox(bbox, origin=ccdOrigin, borderWidth=0.49, ctype=ctype, display=display, bin=binSize) # Label each Amp xc, yc = (ampbbox.getMin()[0] + ampbbox.getMax()[0]) // 2, ( ampbbox.getMin()[1] + ampbbox.getMax()[1]) // 2 # # Rotate the amp labels too # if nQuarter == 0: c, s = 1, 0 elif nQuarter == 1: c, s = 0, -1 elif nQuarter == 2: c, s = -1, 0 elif nQuarter == 3: c, s = 0, 1 c, s = 1, 0 ccdHeight = ccdBbox.getHeight() ccdWidth = ccdBbox.getWidth() xc -= 0.5 * ccdHeight yc -= 0.5 * ccdWidth xc, yc = 0.5 * ccdHeight + c * xc + s * yc, 0.5 * ccdWidth + -s * xc + c * yc if ccdOrigin: xc += ccdOrigin[0] yc += ccdOrigin[1] display.dot(str(amp.getName()), xc / binSize, yc / binSize, textAngle=nQuarter * 90) displayUtils.drawBBox(ccdBbox, origin=ccdOrigin, borderWidth=0.49, ctype=afwDisplay.MAGENTA, display=display, bin=binSize)
def showCamera(camera, imageSource=FakeImageDataSource(), imageFactory=afwImage.ImageF, detectorNameList=None, binSize=10, bufferSize=10, frame=None, overlay=True, title="", ctype=afwDisplay.GREEN, textSize=1.25, originAtCenter=True, display=None, **kwargs): """!Show a Camera on display, with the specified display The rotation of the sensors is snapped to the nearest multiple of 90 deg. Also note that the pixel size is constant over the image array. The lower left corner (LLC) of each sensor amp is snapped to the LLC of the pixel containing the LLC of the image. if overlay show the IDs and detector boundaries @param[in] camera Camera to show @param[in] imageSource Source to get Ccd images from. Must have a getCcdImage method. @param[in] imageFactory Type of image to make @param[in] detectorNameList List of names of Detectors to use. If None use all @param[in] binSize bin factor @param[in] bufferSize size of border in binned pixels to make around camera image. @param[in] frame specify image display (@deprecated; new code should use display) @param[in] overlay Overlay Detector IDs and boundaries? @param[in] title Title in display @param[in] ctype Color to use when drawing Detector boundaries @param[in] textSize Size of detector labels @param[in] originAtCenter Put origin of the camera WCS at the center of the image? Else it will be LL @param[in] display image display on which to display @param[in] **kwargs all remaining keyword arguments are passed to makeImageFromCamera @return the mosaic image """ display = _getDisplayFromDisplayOrFrame(display, frame) if binSize < 1: binSize = 1 cameraImage = makeImageFromCamera(camera, detectorNameList=detectorNameList, bufferSize=bufferSize, imageSource=imageSource, imageFactory=imageFactory, binSize=binSize, **kwargs) if detectorNameList is None: ccdList = [camera[name] for name in camera.getNameIter()] else: ccdList = [camera[name] for name in detectorNameList] if detectorNameList is None: camBbox = camera.getFpBBox() else: camBbox = afwGeom.Box2D() for detName in detectorNameList: for corner in camera[detName].getCorners(FOCAL_PLANE): camBbox.include(corner) pixelSize = ccdList[0].getPixelSize() if originAtCenter: #Can't divide SWIGGED extent type things when division is imported #from future. This is DM-83 ext = cameraImage.getBBox().getDimensions() wcsReferencePixel = afwGeom.PointI(ext.getX()//2, ext.getY()//2) else: wcsReferencePixel = afwGeom.Point2I(0,0) wcs = makeFocalPlaneWcs(pixelSize*binSize, wcsReferencePixel) if display: if title == "": title = camera.getName() display.mtv(cameraImage, title=title, wcs=wcs) if overlay: with display.Buffering(): camBbox = getCameraImageBBox(camBbox, pixelSize, bufferSize*binSize) bboxList = getCcdInCamBBoxList(ccdList, binSize, pixelSize, camBbox.getMin()) for bbox, ccd in itertools.izip(bboxList, ccdList): nQuarter = ccd.getOrientation().getNQuarter() # borderWidth to 0.5 to align with the outside edge of the pixel displayUtils.drawBBox(bbox, borderWidth=0.5, ctype=ctype, display=display) dims = bbox.getDimensions() display.dot(ccd.getName(), bbox.getMinX()+dims.getX()/2, bbox.getMinY()+dims.getY()/2, ctype=ctype, size=textSize, textAngle=nQuarter*90) return cameraImage
def overlayCcdBoxes(ccd, untrimmedCcdBbox=None, nQuarter=0, isTrimmed=False, ccdOrigin=(0, 0), display=None, binSize=1): """Overlay bounding boxes on an image display. Parameters ---------- ccd : `lsst.afw.cameraGeom.Detector` Detector to iterate for the amp bounding boxes. untrimmedCcdBbox : `lsst.geom.Box2I` or None Bounding box of the un-trimmed Detector. nQuarter : `int` number of 90 degree rotations to apply to the bounding boxes (used for rotated chips). isTrimmed : `bool` Is the Detector image over which the boxes are layed trimmed? ccdOrigin : `tuple` of `float` Detector origin relative to the parent origin if in a larger pixel grid. display : `lsst.afw.display.Display` Image display to display on. binSize : `int` Bin the image by this factor in both dimensions. Notes ----- The colours are: - Entire detector GREEN - All data for amp GREEN - HorizontalPrescan YELLOW - HorizontalOverscan RED - Data BLUE - VerticalOverscan MAGENTA - VerticalOverscan MAGENTA """ if not display: # should be second parameter, and not defaulted!! raise RuntimeError("Please specify a display") if untrimmedCcdBbox is None: if isTrimmed: untrimmedCcdBbox = ccd.getBBox() else: untrimmedCcdBbox = lsst.geom.Box2I() for a in ccd.getAmpInfoCatalog(): bbox = a.getRawBBox() untrimmedCcdBbox.include(bbox) with display.Buffering(): ccdDim = untrimmedCcdBbox.getDimensions() ccdBbox = rotateBBoxBy90(untrimmedCcdBbox, nQuarter, ccdDim) for amp in ccd: if isTrimmed: ampbbox = amp.getBBox() else: ampbbox = amp.getRawBBox() if nQuarter != 0: ampbbox = rotateBBoxBy90(ampbbox, nQuarter, ccdDim) displayUtils.drawBBox(ampbbox, origin=ccdOrigin, borderWidth=0.49, display=display, bin=binSize) if not isTrimmed and amp.getHasRawInfo(): for bbox, ctype in ((amp.getRawHorizontalOverscanBBox(), afwDisplay.RED), (amp.getRawDataBBox(), afwDisplay.BLUE), (amp.getRawVerticalOverscanBBox(), afwDisplay.MAGENTA), (amp.getRawPrescanBBox(), afwDisplay.YELLOW)): if nQuarter != 0: bbox = rotateBBoxBy90(bbox, nQuarter, ccdDim) displayUtils.drawBBox(bbox, origin=ccdOrigin, borderWidth=0.49, ctype=ctype, display=display, bin=binSize) # Label each Amp xc, yc = (ampbbox.getMin()[0] + ampbbox.getMax()[0]) // 2, ( ampbbox.getMin()[1] + ampbbox.getMax()[1]) // 2 # # Rotate the amp labels too # if nQuarter == 0: c, s = 1, 0 elif nQuarter == 1: c, s = 0, -1 elif nQuarter == 2: c, s = -1, 0 elif nQuarter == 3: c, s = 0, 1 c, s = 1, 0 ccdHeight = ccdBbox.getHeight() ccdWidth = ccdBbox.getWidth() xc -= 0.5 * ccdHeight yc -= 0.5 * ccdWidth xc, yc = 0.5 * ccdHeight + c * xc + s * yc, 0.5 * ccdWidth + -s * xc + c * yc if ccdOrigin: xc += ccdOrigin[0] yc += ccdOrigin[1] display.dot(str(amp.getName()), xc / binSize, yc / binSize, textAngle=nQuarter * 90) displayUtils.drawBBox(ccdBbox, origin=ccdOrigin, borderWidth=0.49, ctype=afwDisplay.MAGENTA, display=display, bin=binSize)
ISOTROPIC = False N_PIX_MIN = 1 threshold = afwDetect.Threshold(THRESHOLD) footPrintSet = afwDetect.FootprintSet(image, threshold, N_PIX_MIN) footPrintSet = afwDetect.FootprintSet(footPrintSet, GROW, ISOTROPIC) footPrints = footPrintSet.getFootprints() footPrints = footPrintSet.getFootprints() print "Found %s footprints in file %s"%(footPrints.size(), filename) for pointnum, footprint in enumerate(footPrints): displayUtils.drawBBox(footprint.getBBox(), borderWidth=0.5) arg = 'saveimage jpeg ' + str(out_path + str(1) + '_example_frame.jpeg') + ' 100' ds9.ds9Cmd(arg) exit()
image, npix = TimepixToExposure_binary(path + filename, xmin, xmax, ymin, ymax) # image, npix = TimepixToExposure_binary(path + filename, xmin, xmax, ymin, ymax, mask_pixels=pixel_mask) pixels_per_frame_list.append(npix) if DISPLAY == True and filenum == display_num: ds9.mtv(image) threshold = afwDetect.Threshold(thresholdValue) footPrintSet = afwDetect.FootprintSet(image, threshold, npixMin) footPrintSet = afwDetect.FootprintSet(footPrintSet, grow, isotropic) footPrints = footPrintSet.getFootprints() footprint_pixels = 0 ions_per_frame.append(len(footPrints)) for footprint in footPrints: if DISPLAY and filenum == display_num: displayUtils.drawBBox(footprint.getBBox(), borderWidth=0.5) # border to fully encompass the bbox and no more npix = afwDetect.Footprint.getNpix(footprint) cluster_sizes.append(npix) footprint_pixels += npix footprint_pixels_per_frame_list.append(footprint_pixels) # if filenum == display_num: exit() if DISPLAY and filenum == display_num: arg = 'saveimage jpeg ' + str(OUTPUT_PATH + str(val) + '_example_frame.jpeg') + ' 100' ds9.ds9Cmd(arg) histmax = 30 name = 'cluster_size' h1 = ListToHist(cluster_sizes, OUTPUT_PATH + ID + '_cluster_size.png', log_z = False, nbins = histmax-1, histmin = 1, histmax = histmax, name = name)
ds9.setMaskPlaneVisibility('SUSPECT', False) ds9.setMaskPlaneVisibility('WORM', False) # ds9.mtv(exposure.getMaskedImage()) ds9.setMaskPlaneVisibility('MUON', True) ds9.mtv(mi.getImage(), frame = 0, isMask = False, title = 'Image data') # ds9.mtv(mi.getImage(), frame = 1, isMask = False, title = 'Image data2') # ds9.mtv(mi.getMask(), frame = 1, isMask = False, title = 'Mask') # cmd = "-mask mark 0" # ds9.ds9Cmd(cmd) displayUtils.drawBBox(footPrints[9].getBBox(), frame = 1, borderWidth=0.0) footprint = afwDetect.Footprint() xcoords, ycoords = [], [] majors, minors, thetas = [], [], [] ixxs, iyys, ixys = [], [], [] for footprint in footPrints: quadshape = footprint.getShape() ixxs.append(quadshape.getIxx()) iyys.append(quadshape.getIyy()) ixys.append(quadshape.getIxy()) axesshape = Ellipses.Axes(quadshape)
def fitPatches(exp, nx=4, ny=8, bin=None, frame=None, returnResidualImage=False, r=None, lnGrad=None, theta=None): """Fit planes to a set of patches of an image im If r, theta, and lnGrad are provided they should be lists (more accurately, support .append), and they have the values of r, theta, and dlnI/dr from this image appended. """ width, height = exp.getDimensions() if bin is not None: nx, ny = width//bin, height//bin xsize = width//nx ysize = height//ny if frame is not None: frame0 = frame ds9.mtv(exp, title="im", frame=frame) if True else None; frame += 1 if hasattr(exp, "getMaskedImage"): mi = exp.getMaskedImage() ccd = exp.getDetector() else: mi = exp ccd = None try: mi = mi.convertF() except AttributeError: pass if r is not None or lnGrad is not None: assert ccd is not None, "I need a CCD to set r and the logarithmic gradient" assert r is not None and lnGrad is not None, "Please provide both r and lnGrad" z = afwImage.ImageF(nx, ny); za = z.getArray() dlnzdx = afwImage.ImageF(nx, ny); dlnzdxa = dlnzdx.getArray() dlnzdy = afwImage.ImageF(nx, ny); dlnzdya = dlnzdy.getArray() dlnzdr = afwImage.ImageF(nx, ny); dlnzdra = dlnzdr.getArray() if returnResidualImage: residualImage = mi.clone() try: residualImage = residualImage.convertF() except AttributeError: pass else: residualImage = None with ds9.Buffering(): for iy in range(ny): for ix in range(nx): bbox = afwGeom.BoxI(afwGeom.PointI(ix*xsize, iy*ysize), afwGeom.ExtentI(xsize, ysize)) if False and frame is not None: ds9Utils.drawBBox(bbox, frame=frame0) b, res = fitPlane(mi[bbox].getImage(), returnResidualImage=returnResidualImage, niter=5) b[1:] /= b[0] za[iy, ix], dlnzdxa[iy, ix], dlnzdya[iy, ix] = b if returnResidualImage: residualImage[bbox][:] = res if ccd: cen = afwGeom.PointD(bbox.getBegin() + bbox.getDimensions()/2) x, y = ccd.getPositionFromPixel(cen).getMm() # I really want pixels here t = np.arctan2(y, x) dlnzdra[iy, ix] = np.cos(t)*dlnzdxa[iy, ix] + np.sin(t)*dlnzdya[iy, ix] if r is not None: if not (ix in (0, xsize - 1) or iy in (0, ysize - 1)): r.append(np.hypot(x, y)) lnGrad.append(dlnzdra[iy, ix]) if theta is not None: theta.append(t) if frame is not None: if False: ds9.mtv(z, title="z", frame=frame); frame += 1 ds9.mtv(dlnzdx, title="dlnz/dx", frame=frame); frame += 1 ds9.mtv(dlnzdy, title="dlnz/dy", frame=frame); frame += 1 ds9.mtv(residualImage, title="res", frame=frame); frame += 1 ds9.mtv(dlnzdr, title="dlnz/dr %s" % (ccd.getId().getSerial() if ccd else ""), frame=frame); frame += 1 return dlnzdx, dlnzdy, dlnzdr, residualImage
def overlayCcdBoxes(ccd, untrimmedCcdBbox, nQuarter, isTrimmed, ccdOrigin, display, binSize): """!Overlay bounding boxes on an image display @param[in] ccd Detector to iterate for the amp bounding boxes @param[in] untrimmedCcdBbox Bounding box of the un-trimmed Detector @param[in] nQuarter number of 90 degree rotations to apply to the bounding boxes @param[in] isTrimmed Is the Detector image over which the boxes are layed trimmed? @param[in] ccdOrigin Detector origin relative to the parent origin if in a larger pixel grid @param[in] display image display to display on @param[in] binSize binning factor """ with display.Buffering(): ccdDim = untrimmedCcdBbox.getDimensions() ccdBbox = rotateBBoxBy90(untrimmedCcdBbox, nQuarter, ccdDim) for amp in ccd: if isTrimmed: ampbbox = amp.getBBox() else: ampbbox = amp.getRawBBox() ampbbox.shift(amp.getRawXYOffset()) if nQuarter != 0: ampbbox = rotateBBoxBy90(ampbbox, nQuarter, ccdDim) displayUtils.drawBBox(ampbbox, origin=ccdOrigin, borderWidth=0.49, display=display, bin=binSize) if not isTrimmed and amp.getHasRawInfo(): for bbox, ctype in ((amp.getRawHorizontalOverscanBBox(), afwDisplay.RED), (amp.getRawDataBBox(), afwDisplay.BLUE), (amp.getRawVerticalOverscanBBox(), afwDisplay.MAGENTA), (amp.getRawPrescanBBox(), afwDisplay.YELLOW)): if amp.getRawFlipX(): bbox.flipLR(amp.getRawBBox().getDimensions().getX()) if amp.getRawFlipY(): bbox.flipTB(amp.getRawBBox().getDimensions().getY()) bbox.shift(amp.getRawXYOffset()) if nQuarter != 0: bbox = rotateBBoxBy90(bbox, nQuarter, ccdDim) displayUtils.drawBBox(bbox, origin=ccdOrigin, borderWidth=0.49, ctype=ctype, display=display, bin=binSize) # Label each Amp xc, yc = (ampbbox.getMin()[0] + ampbbox.getMax()[0])//2, (ampbbox.getMin()[1] + ampbbox.getMax()[1])//2 # # Rotate the amp labels too # if nQuarter == 0: c, s = 1, 0 elif nQuarter == 1: c, s = 0, -1 elif nQuarter == 2: c, s = -1, 0 elif nQuarter == 3: c, s = 0, 1 c, s = 1, 0 ccdHeight = ccdBbox.getHeight() ccdWidth = ccdBbox.getWidth() xc -= 0.5*ccdHeight yc -= 0.5*ccdWidth xc, yc = 0.5*ccdHeight + c*xc + s*yc, 0.5*ccdWidth + -s*xc + c*yc if ccdOrigin: xc += ccdOrigin[0] yc += ccdOrigin[1] display.dot(str(amp.getName()), xc/binSize, yc/binSize, textAngle=nQuarter*90) displayUtils.drawBBox(ccdBbox, origin=ccdOrigin, borderWidth=0.49, ctype=afwDisplay.MAGENTA, display=display, bin=binSize)
def cosmicRay(self, exposure, keepCRs=None): """Mask cosmic rays \param[in,out] exposure Exposure to process \param[in] keepCRs Don't interpolate over the CR pixels (defer to pex_config if None) """ import lsstDebug display = lsstDebug.Info(__name__).display displayCR = lsstDebug.Info(__name__).displayCR assert exposure, "No exposure provided" psf = exposure.getPsf() assert psf, "No psf provided" # Blow away old mask try: mask = exposure.getMaskedImage().getMask() crBit = mask.getMaskPlane("CR") mask.clearMaskPlane(crBit) except Exception: pass exposure0 = exposure # initial value of exposure binSize = self.config.cosmicray.background.binSize nx, ny = exposure.getWidth()/binSize, exposure.getHeight()/binSize # Treat constant background as a special case to avoid the extra complexity in calling # measAlg.SubtractBackgroundTask(). if nx*ny <= 1: medianBg = afwMath.makeStatistics(exposure.getMaskedImage(), afwMath.MEDIAN).getValue() modelBg = None else: # make a deep copy of the exposure before subtracting its background, # because this routine is only allowed to modify the exposure by setting mask planes # and interpolating over defects, not changing the background level exposure = exposure.Factory(exposure, True) subtractBackgroundTask = measAlg.SubtractBackgroundTask(config=self.config.cosmicray.background) modelBg = subtractBackgroundTask.run(exposure).background medianBg = 0.0 if keepCRs is None: keepCRs = self.config.cosmicray.keepCRs try: crs = measAlg.findCosmicRays(exposure.getMaskedImage(), psf, medianBg, pexConfig.makePolicy(self.config.cosmicray), keepCRs) if modelBg: # Add back background image img = exposure.getMaskedImage() img += modelBg.getImageF() del img # Replace original image with CR subtracted image exposure0.setMaskedImage(exposure.getMaskedImage()) except Exception: if display: import lsst.afw.display.ds9 as ds9 ds9.mtv(exposure0, title="Failed CR") raise num = 0 if crs is not None: mask = exposure0.getMaskedImage().getMask() crBit = mask.getPlaneBitMask("CR") afwDet.setMaskFromFootprintList(mask, crs, crBit) num = len(crs) if display and displayCR: import lsst.afw.display.ds9 as ds9 import lsst.afw.display.utils as displayUtils ds9.incrDefaultFrame() ds9.mtv(exposure0, title="Post-CR") with ds9.Buffering(): for cr in crs: displayUtils.drawBBox(cr.getBBox(), borderWidth=0.55) self.log.info("Identified %s cosmic rays." % (num,))
def showCcd(ccd, ccdImage="", amp=None, ccdOrigin=None, isTrimmed=None, frame=None, overlay=True, bin=1): """Show a CCD on ds9. If cameraImage is "", an image will be created based on the properties of the detectors""" if isTrimmed is None: isTrimmed = ccd.isTrimmed() if ccdImage == "": ccdImage = makeImageFromCcd(ccd, bin=bin) if ccdImage: title = ccd.getId().getName() if amp: title += ":%d" % amp.getId().getSerial() if isTrimmed: title += "(trimmed)" ds9.mtv(ccdImage, frame=frame, title=title) if not overlay: return if amp: bboxes = [(amp.getAllPixels(isTrimmed), 0.49, None),] xy0 = bboxes[0][0].getMin() if not isTrimmed: bboxes.append((amp.getBiasSec(), 0.49, ds9.RED)) bboxes.append((amp.getDataSec(), 0.49, ds9.BLUE)) for bbox, borderWidth, ctype in bboxes: bbox = bbox.clone() bbox.shift(-afwGeom.ExtentI(xy0)) displayUtils.drawBBox(bbox, borderWidth=borderWidth, ctype=ctype, frame=frame, bin=bin) return nQuarter = ccd.getOrientation().getNQuarter() ccdDim = ccd.getAllPixels(isTrimmed).getDimensions() for a in ccd: bbox = a.getAllPixels(isTrimmed) if nQuarter != 0: bbox = cameraGeom.rotateBBoxBy90(bbox, nQuarter, ccdDim) displayUtils.drawBBox(bbox, origin=ccdOrigin, borderWidth=0.49, frame=frame, bin=bin) if not isTrimmed: for bbox, ctype in ((a.getBiasSec(), ds9.RED), (a.getDataSec(), ds9.BLUE)): if nQuarter != 0: bbox = cameraGeom.rotateBBoxBy90(bbox, nQuarter, ccdDim) displayUtils.drawBBox(bbox, origin=ccdOrigin, borderWidth=0.49, ctype=ctype, frame=frame, bin=bin) # Label each Amp ap = a.getAllPixels(isTrimmed) xc, yc = (ap.getX0() + ap.getX1())//2, (ap.getY0() + ap.getY1())//2 cen = afwGeom.makePointI(xc, yc) # # Rotate the amp labels too # if nQuarter == 0: c, s = 1, 0 elif nQuarter == 1: c, s = 0, -1 elif nQuarter == 2: c, s = -1, 0 elif nQuarter == 3: c, s = 0, 1 xc -= 0.5*ccdHeight yc -= 0.5*ccdWidth xc, yc = 0.5*ccdHeight + c*xc + s*yc, 0.5*ccdWidth + -s*xc + c*yc if ccdOrigin: xc += ccdOrigin[0] yc += ccdOrigin[1] ds9.dot(str(ccd.findAmp(cen).getId().getSerial()), xc/bin, yc/bin, frame=frame) displayUtils.drawBBox(ccd.getAllPixels(isTrimmed), origin=ccdOrigin, borderWidth=0.49, ctype=ds9.MAGENTA, frame=frame, bin=bin)
def overlayCcdBoxes(ccd, untrimmedCcdBbox=None, nQuarter=0, isTrimmed=False, ccdOrigin=(0, 0), display=None, binSize=1): """Overlay bounding boxes on an image display. Parameters ---------- ccd : `lsst.afw.cameraGeom.Detector` Detector to iterate for the amp bounding boxes. untrimmedCcdBbox : `lsst.geom.Box2I` or `None` Bounding box of the un-trimmed Detector. nQuarter : `int` number of 90 degree rotations to apply to the bounding boxes (used for rotated chips). isTrimmed : `bool` Is the Detector image over which the boxes are layed trimmed? ccdOrigin : `tuple` of `float` Detector origin relative to the parent origin if in a larger pixel grid. display : `lsst.afw.display.Display` Image display to display on. binSize : `int` Bin the image by this factor in both dimensions. Notes ----- The colours are: - Entire detector GREEN - All data for amp GREEN - HorizontalPrescan YELLOW - HorizontalOverscan RED - Data BLUE - VerticalOverscan MAGENTA - VerticalOverscan MAGENTA """ if not display: # should be second parameter, and not defaulted!! raise RuntimeError("Please specify a display") if untrimmedCcdBbox is None: if isTrimmed: untrimmedCcdBbox = ccd.getBBox() else: untrimmedCcdBbox = lsst.geom.Box2I() for a in ccd.getAmpInfoCatalog(): bbox = a.getRawBBox() untrimmedCcdBbox.include(bbox) with display.Buffering(): ccdDim = untrimmedCcdBbox.getDimensions() ccdBbox = rotateBBoxBy90(untrimmedCcdBbox, nQuarter, ccdDim) for amp in ccd: if isTrimmed: ampbbox = amp.getBBox() else: ampbbox = amp.getRawBBox() if nQuarter != 0: ampbbox = rotateBBoxBy90(ampbbox, nQuarter, ccdDim) displayUtils.drawBBox(ampbbox, origin=ccdOrigin, borderWidth=0.49, display=display, bin=binSize) if not isTrimmed and amp.getHasRawInfo(): for bbox, ctype in ((amp.getRawHorizontalOverscanBBox(), afwDisplay.RED), (amp.getRawDataBBox(), afwDisplay.BLUE), (amp.getRawVerticalOverscanBBox(), afwDisplay.MAGENTA), (amp.getRawPrescanBBox(), afwDisplay.YELLOW)): if nQuarter != 0: bbox = rotateBBoxBy90(bbox, nQuarter, ccdDim) displayUtils.drawBBox(bbox, origin=ccdOrigin, borderWidth=0.49, ctype=ctype, display=display, bin=binSize) # Label each Amp xc, yc = (ampbbox.getMin()[0] + ampbbox.getMax()[0])//2, (ampbbox.getMin()[1] + ampbbox.getMax()[1])//2 # # Rotate the amp labels too # if nQuarter == 0: c, s = 1, 0 elif nQuarter == 1: c, s = 0, -1 elif nQuarter == 2: c, s = -1, 0 elif nQuarter == 3: c, s = 0, 1 c, s = 1, 0 ccdHeight = ccdBbox.getHeight() ccdWidth = ccdBbox.getWidth() xc -= 0.5*ccdHeight yc -= 0.5*ccdWidth xc, yc = 0.5*ccdHeight + c*xc + s*yc, 0.5*ccdWidth + -s*xc + c*yc if ccdOrigin: xc += ccdOrigin[0] yc += ccdOrigin[1] display.dot(str(amp.getName()), xc/binSize, yc/binSize, textAngle=nQuarter*90) displayUtils.drawBBox(ccdBbox, origin=ccdOrigin, borderWidth=0.49, ctype=afwDisplay.MAGENTA, display=display, bin=binSize)