def testBin(self): """Test that we can bin images anisotropically""" inImage = afwImage.ImageF(203, 131) val = 1 inImage.set(val) binX, binY = 2, 4 outImage = afwMath.binImage(inImage, binX, binY) self.assertEqual(outImage.getWidth(), inImage.getWidth()//binX) self.assertEqual(outImage.getHeight(), inImage.getHeight()//binY) stats = afwMath.makeStatistics(outImage, afwMath.MAX | afwMath.MIN) self.assertEqual(stats.getValue(afwMath.MIN), val) self.assertEqual(stats.getValue(afwMath.MAX), val) inImage.set(0) subImg = inImage.Factory(inImage, afwGeom.BoxI(afwGeom.PointI(4, 4), afwGeom.ExtentI(4, 8)), afwImage.LOCAL) subImg.set(100) del subImg outImage = afwMath.binImage(inImage, binX, binY) if display: ds9.mtv(inImage, frame=2, title="unbinned") ds9.mtv(outImage, frame=3, title="binned %dx%d" % (binX, binY))
def testImageSlices(self): """Test image slicing, which generate sub-images using Box2I under the covers""" im = afwImage.ImageF(10, 20) im[-1, :] = -5 im[..., 18] = -5 # equivalent to im[:, 18] im[4, 10] = 10 im[-3:, -2:] = 100 im[-2, -2] = -10 sim = im[1:4, 6:10] sim[:] = -1 im[0:4, 0:4] = im[2:6, 8:12] if display: ds9.mtv(im) self.assertEqual(im.get(0, 6), 0) self.assertEqual(im.get(9, 15), -5) self.assertEqual(im.get(5, 18), -5) self.assertEqual(im.get(6, 17), 0) self.assertEqual(im.get(7, 18),100) self.assertEqual(im.get(9, 19),100) self.assertEqual(im.get(8, 18),-10) self.assertEqual(im.get(1, 6), -1) self.assertEqual(im.get(3, 9), -1) self.assertEqual(im.get(4, 10), 10) self.assertEqual(im.get(4, 9), 0) self.assertEqual(im.get(2, 2), 10) self.assertEqual(im.get(0, 0), -1)
def checkCandidateMasking(self, badPixels, extraPixels=[], size=25, threshold=0.1, pixelThreshold=0.0): """Check that candidates are masked properly We add various pixels to the image and investigate the masking. @param badPixels: (x,y,flux) triplet of pixels that should be masked @param extraPixels: (x,y,flux) triplet of additional pixels to add to image @param size: Size of candidate @param threshold: Threshold for creating footprints on image @param pixelThreshold: Threshold for masking pixels on candidate """ image = self.exp.getMaskedImage().getImage() for x,y,f in badPixels + extraPixels: image[x,y] = f cand = self.createCandidate(threshold=threshold) oldPixelThreshold = cand.getPixelThreshold() try: cand.setPixelThreshold(pixelThreshold) candImage = cand.getMaskedImage(size, size) mask = candImage.getMask() if display: ds9.mtv(candImage, frame=2) ds9.mtv(candImage.getMask().convertU(), frame=3) detected = mask.getMaskPlane("DETECTED") intrp = mask.getMaskPlane("INTRP") for x,y,f in badPixels: x -= self.x - size//2 y -= self.y - size//2 self.assertTrue(mask.get(x, y, intrp)) self.assertFalse(mask.get(x, y, detected)) finally: # Ensure this static variable is reset cand.setPixelThreshold(oldPixelThreshold)
def testSingleExposure(self): policyFile = pexPolicy.DefaultPolicyFile("ip_pipeline", "DiffImStageDictionary.paf", "policy") policy = pexPolicy.Policy.createPolicy(policyFile, policyFile.getRepositoryPath(), True) self.subBackground(policy.get("diffImPolicy").get("backgroundPolicy")) stage = ipPipe.DiffImStage(policy) tester = SimpleStageTester(stage) #print policy clipboard = pexClipboard.Clipboard() clipboard.put(policy.get("inputKeys.templateExposureKey"), self.templateExposure) clipboard.put(policy.get("inputKeys.scienceExposureKey"), self.scienceExposure) outWorker = tester.runWorker(clipboard) outPolicy = policy.get("outputKeys") #print outPolicy self.assertTrue(outWorker.contains(outPolicy.get("differenceExposureKey"))) self.assertTrue(outWorker.contains(outPolicy.get("psfMatchingKernelKey"))) self.assertTrue(outWorker.contains(outPolicy.get("backgroundFunctionKey"))) # also check types diffExposure = outWorker.get(outPolicy.get("differenceExposureKey")) matchingKernel = outWorker.get(outPolicy.get("psfMatchingKernelKey")) background = outWorker.get(outPolicy.get("backgroundFunctionKey")) self.assertTrue(isinstance(diffExposure, afwImage.ExposureF)) self.assertTrue(isinstance(matchingKernel, afwMath.LinearCombinationKernel)) self.assertTrue(isinstance(background, afwMath.Function2D)) if display: ds9.mtv(outWorker.get(outPolicy.get("differenceExposureKey")), frame=5)
def readSExtractor(filename): with pyfits.open(filename) as pf: for hdu in pf: if hdu.name == "PRIMARY": pass elif hdu.name == "LDAC_IMHEAD": hdr = hdu.data[0][0] # the fits header from the original fits image print hdr[3] elif hdu.name == "LDAC_OBJECTS": print "%d objects" % (len(hdu.data)) # Find the VIGNET column ttype = [k for k, v in hdu.header.items() if v == "VIGNET"] if not ttype: raise RuntimeError("Unable to find a VIGNET column") vignetCol = int(re.search(r"^TTYPE(\d+)$", ttype[0]).group(1)) - 1 for row in range(len(hdu.data)): pixelData = hdu.data[row][vignetCol] bad = np.where(pixelData < -1e29) sat = np.where(pixelData > 99e3) pixelData[bad] = 0.0 mi = afwImage.MaskedImageF(*hdu.data[row][vignetCol].shape) im = mi.getImage() im.getArray()[:] = pixelData msk = mi.getMask().getArray() msk[bad] = afwImage.MaskU.getPlaneBitMask("BAD") msk[sat] = afwImage.MaskU.getPlaneBitMask("SAT") ds9.mtv(mi, title=row) raw_input("Next ")
def testKernelPsf(self): """Test creating a Psf from a Kernel""" x,y = 10.4999, 10.4999 ksize = 15 sigma1 = 1 # # Make a PSF from that kernel # kPsf = measAlg.KernelPsf(afwMath.AnalyticKernel(ksize, ksize, afwMath.GaussianFunction2D(sigma1, sigma1))) kIm = kPsf.computeImage(afwGeom.Point2D(x, y)) # # And now via the dgPsf model # dgPsf = measAlg.DoubleGaussianPsf(ksize, ksize, sigma1) dgIm = dgPsf.computeImage(afwGeom.Point2D(x, y)) # # Check that they're the same # diff = type(kIm)(kIm, True); diff -= dgIm stats = afwMath.makeStatistics(diff, afwMath.MAX | afwMath.MIN) self.assertAlmostEqual(stats.getValue(afwMath.MAX), 0.0, places=16) self.assertAlmostEqual(stats.getValue(afwMath.MIN), 0.0, places=16) if display: mos = displayUtils.Mosaic() mos.setBackground(-0.1) ds9.mtv(mos.makeMosaic([kIm, dgIm, diff], mode="x"), frame=1)
def testCFHT_oldAPI(self): """Test background subtraction on some real CFHT data""" afwdataDir = eups.productDir("afwdata") if not afwdataDir: print >> sys.stderr, "Skipping testCFHT as afwdata is not setup" return mi = afwImage.MaskedImageF(os.path.join(afwdataDir, "CFHT", "D4", "cal-53535-i-797722_1")) mi = mi.Factory(mi, afwGeom.Box2I(afwGeom.Point2I(32, 2), afwGeom.Point2I(2079, 4609)), afwImage.LOCAL) bctrl = afwMath.BackgroundControl(afwMath.Interpolate.AKIMA_SPLINE) bctrl.setNxSample(16) bctrl.setNySample(16) bctrl.getStatisticsControl().setNumSigmaClip(3.0) bctrl.getStatisticsControl().setNumIter(2) backobj = afwMath.makeBackground(mi.getImage(), bctrl) if display: ds9.mtv(mi, frame = 0) im = mi.getImage() im -= backobj.getImageF() if display: ds9.mtv(mi, frame = 1)
def saveSpatialCellSet(psfCellSet, fileName="foo.fits", frame=None): """Write the contents of a SpatialCellSet to a many-MEF fits file""" mode = "w" for cell in psfCellSet.getCellList(): for cand in cell.begin(False): # include bad candidates cand = algorithmsLib.cast_PsfCandidateF(cand) dx = afwImage.positionToIndex(cand.getXCenter(), True)[1] dy = afwImage.positionToIndex(cand.getYCenter(), True)[1] im = afwMath.offsetImage(cand.getMaskedImage(), -dx, -dy, "lanczos5") md = dafBase.PropertySet() md.set("CELL", cell.getLabel()) md.set("ID", cand.getId()) md.set("XCENTER", cand.getXCenter()) md.set("YCENTER", cand.getYCenter()) md.set("BAD", cand.isBad()) md.set("AMPL", cand.getAmplitude()) md.set("FLUX", cand.getSource().getPsfFlux()) md.set("CHI2", cand.getSource().getChi2()) im.writeFits(fileName, md, mode) mode = "a" if frame is not None: ds9.mtv(im, frame=frame)
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 main(rootDir, visit, ccd, frame=1, title="", scale="zscale", zoom="to fit", trans=60, useEllipse=False): # make a butler and specify your dataId butler = dafPersist.Butler(rootDir) dataId = {'visit': visit, 'ccd':ccd} # get the exposure from the butler exposure = butler.get('calexp', dataId) # put the settings in a dict object and call ds9.mtv() settings = {'scale':scale, 'zoom': zoom, 'mask' : 'transparency %d' %(trans)} ds9.mtv(exposure, frame=frame, title=title, settings=settings) # now get the source catalog and overplot the points sources = butler.get('src', dataId) with ds9.Buffering(): for i,source in enumerate(sources): color = ds9.RED size = 5.0 if useEllipse: # show an ellipse symbol symbol = "@:{ixx},{ixy},{iyy}".format(ixx=source.getIxx(), ixy=source.getIxy(), iyy=source.getIyy()) else: # just a simple point (symbols +, x, *, o are all accepted) symbol = "o" ds9.dot(symbol, source.getX(), source.getY(), ctype=color, size=size, frame=frame, silent=True)
def testGetImage(self): """Test returning a realisation of the dgPsf""" xcen = self.psf.getKernel().getWidth()//2 ycen = self.psf.getKernel().getHeight()//2 stamps = [] trueCenters = [] for x, y in ([10, 10], [9.4999, 10.4999], [10.5001, 10.5001]): fx, fy = x - int(x), y - int(y) if fx >= 0.5: fx -= 1.0 if fy >= 0.5: fy -= 1.0 im = self.psf.computeImage(afwGeom.Point2D(x, y)).convertF() stamps.append(im.Factory(im, True)) trueCenters.append([xcen + fx, ycen + fy]) if display: mos = displayUtils.Mosaic() # control mosaics ds9.mtv(mos.makeMosaic(stamps)) for i in range(len(trueCenters)): bbox = mos.getBBox(i) ds9.dot("+", bbox.getMinX() + xcen, bbox.getMinY() + ycen, ctype = ds9.RED, size = 1) ds9.dot("+", bbox.getMinX() + trueCenters[i][0], bbox.getMinY() + trueCenters[i][1]) ds9.dot("%.2f, %.2f" % (trueCenters[i][0], trueCenters[i][1]), bbox.getMinX() + xcen, bbox.getMinY() + 2)
def showCcd(ccd, imageSource=FakeImageDataSource(), frame=None, overlay=True, imageFactory=afwImage.ImageU, binSize=1, inCameraCoords=False): """!Show a CCD on ds9 @param[in] ccd Detector to use in display @param[in] imageSource Source for producing images to display. Must have a getCcdImage method. @param[in] frame ds9 frame to use, defaults to frame zero @param[in] overlay Show amp bounding boxes on the displayed image? @param[in] imageFactory The image factory to use in generating the images. @param[in] binSize Binning factor @param[in] inCameraCoords Show the Detector in camera coordinates? """ ccdOrigin = afwGeom.Point2I(0,0) nQuarter = 0 ccdImage = imageSource.getCcdImage(ccd, imageFactory=imageFactory, binSize=binSize) ccdBbox = ccdImage.getBBox() if ccdBbox.getDimensions() == ccd.getBBox().getDimensions(): isTrimmed = True else: isTrimmed = False if inCameraCoords: nQuarter = ccd.getOrientation().getNQuarter() ccdImage = afwMath.rotateImageBy90(ccdImage, nQuarter) title = ccd.getName() if isTrimmed: title += "(trimmed)" ds9.mtv(ccdImage, frame=frame, title=title) if overlay: overlayCcdBoxes(ccd, ccdBbox, nQuarter, isTrimmed, ccdOrigin, frame, binSize)
def testSingleExposure(self): file = pexPolicy.DefaultPolicyFile("meas_pipeline", "backgroundEstimation_policy.paf", "tests") policy = pexPolicy.Policy.createPolicy(file) stage = measPipe.BackgroundEstimationStage(policy) tester = SimpleStageTester(stage) clipboard = pexClipboard.Clipboard() clipboard.put(policy.get("inputKeys.exposure"), self.exposure) if display: ds9.mtv(self.exposure, frame=0, title="Input") # # Do the work # outWorker = tester.runWorker(clipboard) outPolicy = policy.get("outputKeys") assert(outWorker.contains(outPolicy.get("backgroundSubtractedExposure"))) assert(outWorker.contains(outPolicy.get("background"))) if display: ds9.mtv(outWorker.get(outPolicy.get("backgroundSubtractedExposure")), frame=1, title="Subtracted")
def getMosaic(sources, exposure, idname): """ make a ds9 mosaic for the given source list from the given exposure stolen from psfMosaic.py on the sphinx documentation """ img = exposure.getMaskedImage().getImage() subImages=[] labels = [] for src in sources: footBBox = src.getFootprint().getBBox() subimg = lsst.afw.image.ImageF(img, footBBox, lsst.afw.image.PARENT, True) footMask = lsst.afw.image.ImageU(footBBox) src.getFootprint().insertIntoImage(footMask, 1, footBBox) subimg *= footMask.convertF() subImages.append(subimg) labels.append('ID=%s'%str(src.get(idname))) m = lsst.afw.display.utils.Mosaic() m.setGutter(2) m.setBackground(0) m.setMode("square") # create the mosaic for img in subImages: m.append(img) mosaic = m.makeMosaic() # display it with labels in ds9 ds9.mtv(mosaic) m.drawLabels(labels)
def testComputeImage(self): """Test the computation of the PSF's image at a point""" ccdXY = afwGeom.Point2D(0, 0) kIm = self.psf.computeImage(ccdXY) if False: ds9.mtv(kIm) self.assertTrue(kIm.getWidth() == self.ksize) # # Check that the image is as expected. # xcen, ycen = self.ksize/2, self.ksize/2 I0 = kIm.get(xcen, ycen) self.assertAlmostEqual(kIm.get(xcen + 1, ycen + 1), I0*self.psf.computeImage().get(xcen + 1, ycen + 1)) # # Is image normalised to a peak value of unity? # self.assertAlmostEqual(afwMath.makeStatistics(kIm, afwMath.MAX).getValue(), 1.0) # # Now create a normalised version # kIm = self.psf.computeImage(ccdXY, False) self.assertAlmostEqual(afwMath.makeStatistics(kIm, afwMath.SUM).getValue(), 1.0)
def showCamera(camera, imageSource=SynthesizeCcdImage(), imageFactory=afwImage.ImageU, frame=None, overlay=True, bin=1): """Show a Camera on ds9 (with the specified frame); if overlay show the IDs and amplifier boundaries If imageSource is provided its getImage method will be called to return a CCD image (e.g. a cameraGeom.GetCcdImage object); if it is "", an image will be created based on the properties of the detectors""" if imageSource is None: cameraImage = None elif isinstance(imageSource, GetCcdImage): cameraImage = makeImageFromCamera(camera, imageSource, bin=bin, imageFactory=imageFactory) else: cameraImage = imageSource if cameraImage: ds9.mtv(cameraImage, frame=frame, title=camera.getId().getName()) for det in camera: raft = cameraGeom.cast_Raft(det) center = camera.getCenterPixel() + afwGeom.Extent2D(raft.getCenterPixel()) if overlay: bbox = raft.getAllPixels() ds9.dot(raft.getId().getName(), center[0]/bin, center[1]/bin, frame=frame) showRaft(raft, None, frame=frame, overlay=overlay, raftOrigin=center - afwGeom.makeExtentD(raft.getAllPixels().getWidth()/2, raft.getAllPixels().getHeight()/2), bin=bin)
def testNaNFromMaskedImage(self): """Check that an extensively masked image doesn't lead to NaNs in the background estimation """ image = afwImage.MaskedImageF(800, 800) msk = image.getMask() bbox = afwGeom.BoxI(afwGeom.PointI(560, 0), afwGeom.PointI(799, 335)) smsk = msk.Factory(msk, bbox) smsk.set(msk.getPlaneBitMask("DETECTED")) binSize = 256 nx = image.getWidth()//binSize + 1 ny = image.getHeight()//binSize + 1 sctrl = afwMath.StatisticsControl() sctrl.setAndMask(reduce(lambda x, y: x | image.getMask().getPlaneBitMask(y), ['EDGE', 'DETECTED', 'DETECTED_NEGATIVE'], 0x0)) bctrl = afwMath.BackgroundControl(nx, ny, sctrl, "MEANCLIP") bkgd = afwMath.makeBackground(image, bctrl) bkgdImage = bkgd.getImageF("NATURAL_SPLINE", "THROW_EXCEPTION") if display: ds9.mtv(image) ds9.mtv(bkgdImage, frame=1) self.assertFalse(np.isnan(bkgdImage.get(0,0))) # Check that the non-string API works too bkgdImage = bkgd.getImageF(afwMath.Interpolate.NATURAL_SPLINE, afwMath.THROW_EXCEPTION)
def measure(footprintSet, exposure): """Measure a set of Footprints, returning a SourceCatalog""" schema = afwTable.SourceTable.makeMinimalSchema() config = measBase.SingleFrameMeasurementConfig() config.algorithms.names = ["base_PixelFlags", "base_SdssCentroid", "base_GaussianFlux", "base_SdssShape", "base_CircularApertureFlux", "base_PsfFlux", ] config.algorithms["base_CircularApertureFlux"].radii = [3.0] config.slots.centroid = "base_SdssCentroid" config.slots.psfFlux = "base_PsfFlux" config.slots.apFlux = "base_CircularApertureFlux_3_0" config.slots.modelFlux = None config.slots.instFlux = None config.slots.calibFlux = None config.slots.shape = "base_SdssShape" task = measBase.SingleFrameMeasurementTask(schema, config=config) table = afwTable.SourceCatalog(schema) footprintSet.makeSources(table) # Then run the default SFM task. Results not checked task.run(table, exposure) if display: ds9.mtv(exposure) return table
def testInvarianceOfPixelToSky(self): for deep in (True, False): llc = afwGeom.Point2I(20, 30) bbox = afwGeom.Box2I(llc, afwGeom.Extent2I(60, 50)) subImg = afwImage.ExposureF(self.parent, bbox, afwImage.LOCAL, deep) xy0 = subImg.getMaskedImage().getXY0() if False: ds9.mtv(self.parent, frame=0) ds9.mtv(subImg, frame=1) for p in self.testPositions: subP = p - afwGeom.Extent2D(llc[0], llc[1]) # pixel in subImg if subP[0] < 0 or subP[0] >= bbox.getWidth() or subP[1] < 0 or subP[1] >= bbox.getHeight(): continue adParent = self.parent.getWcs().pixelToSky(p) adSub = subImg.getWcs().pixelToSky(subP + afwGeom.Extent2D(xy0[0], xy0[1])) # # Check that we're talking about the same pixel # self.assertEqual( self.parent.getMaskedImage().get(int(p[0]), int(p[1])), subImg.getMaskedImage().get(int(subP[0]), int(subP[1])), ) self.assertEqual(adParent[0], adSub[0], "RAs are equal; deep = %s" % deep) self.assertEqual(adParent[1], adSub[1], "DECs are equal; deep = %s" % deep)
def run(self, dataRef): """!Compute a few statistics on the image plane of an exposure @param dataRef: data reference for a calibrated science exposure ("calexp") @return a pipeBase Struct containing: - mean: mean of image plane - meanErr: uncertainty in mean - stdDev: standard deviation of image plane - stdDevErr: uncertainty in standard deviation """ self.log.info("Processing data ID %s" % (dataRef.dataId,)) if self.config.doFail: raise pipeBase.TaskError("Raising TaskError by request (config.doFail=True)") # Unpersist the raw exposure pointed to by the data reference rawExp = dataRef.get("raw") maskedImage = rawExp.getMaskedImage() # Support extra debug output. # - import lsstDebug display = lsstDebug.Info(__name__).display if display: frame = 1 mtv(rawExp, frame=frame, title="exposure") # return the pipe_base Struct that is returned by self.stats.run return self.stats.run(maskedImage)
def testFootprintFromEllipse(self): """Create an elliptical Footprint""" cen = afwGeom.Point2D(23, 25) a, b, theta = 25, 15, 30 ellipse = afwGeomEllipses.Ellipse(afwGeomEllipses.Axes(a, b, math.radians(theta)), cen) foot = afwDetect.Footprint(ellipse, afwGeom.Box2I(afwGeom.Point2I(0, 0), afwGeom.Extent2I(50, 60))) idImage = afwImage.ImageU(afwGeom.Extent2I(foot.getRegion().getWidth(), foot.getRegion().getHeight())) idImage.set(0) foot.insertIntoImage(idImage, foot.getId()) if display: ds9.mtv(idImage, frame=2) displayUtils.drawFootprint(foot, frame=2) shape = foot.getShape() shape.scale(2) # <r^2> = 1/2 for a disk ds9.dot(shape, *cen, frame=2, ctype=ds9.RED) shape = foot.getShape() shape.scale(2) # <r^2> = 1/2 for a disk ds9.dot(shape, *cen, frame=2, ctype=ds9.MAGENTA) axes = afwGeom.ellipses.Axes(foot.getShape()) axes.scale(2) # <r^2> = 1/2 for a disk self.assertEqual(foot.getCentroid(), cen) self.assertTrue(abs(a - axes.getA()) < 0.15, "a: %g v. %g" % (a, axes.getA())) self.assertTrue(abs(b - axes.getB()) < 0.02, "b: %g v. %g" % (b, axes.getB())) self.assertTrue(abs(theta - math.degrees(axes.getTheta())) < 0.2, "theta: %g v. %g" % (theta, math.degrees(axes.getTheta())))
def testGrowCircular(self): """Grow footprints in all 4 directions using the FootprintSet/FootprintControl constructor """ im = afwImage.MaskedImageF(11, 11) im.set(5, 5, (10,)) fs = afwDetect.FootprintSet(im, afwDetect.Threshold(10)) self.assertEqual(len(fs.getFootprints()), 1) radius = 3 # How much to grow by for fctrl in ( afwDetect.FootprintControl(), afwDetect.FootprintControl(True), afwDetect.FootprintControl(True, True), ): grown = afwDetect.FootprintSet(fs, radius, fctrl) afwDetect.setMaskFromFootprintList(im.getMask(), grown.getFootprints(), 0x10) if display: ds9.mtv(im) foot = grown.getFootprints()[0] if not fctrl.isCircular()[0]: self.assertEqual(foot.getNpix(), 1) elif fctrl.isCircular()[0]: assert radius == 3 if fctrl.isIsotropic()[1]: self.assertEqual(foot.getNpix(), 29) else: self.assertEqual(foot.getNpix(), 25)
def testGrowLRUD2(self): """Grow footprints in various directions using the FootprintSet/FootprintControl constructor Check that overlapping grown Footprints give the expected answers """ ngrow = 3 # How much to grow by for fctrl, xy in [ (afwDetect.FootprintControl(True, True, False, False), [(4, 5), (5, 6), (6, 5)]), (afwDetect.FootprintControl(False, False, True, True), [(5, 4), (6, 5), (5, 6)]), ]: im = afwImage.MaskedImageF(11, 11) for x, y in xy: im.set(x, y, (10,)) fs = afwDetect.FootprintSet(im, afwDetect.Threshold(10)) self.assertEqual(len(fs.getFootprints()), 1) grown = afwDetect.FootprintSet(fs, ngrow, fctrl) im.getMask().set(0) afwDetect.setMaskFromFootprintList(im.getMask(), grown.getFootprints(), 0x10) if display: ds9.mtv(im) self.assertEqual(len(grown.getFootprints()), 1) foot = grown.getFootprints()[0] npix = 1 + 2 * ngrow npix += 3 + 2 * ngrow # 3: distance between pair of set pixels 000X0X000 self.assertEqual(foot.getNpix(), npix)
def setUp(self): self.ms = afwImage.MaskedImageF(afwGeom.Extent2I(12, 8)) im = self.ms.getImage() # # Objects that we should detect # self.objects = [] self.objects += [Object(10, [(1, 4, 4), (2, 3, 5), (3, 4, 4)])] self.objects += [Object(20, [(5, 7, 8), (6, 8, 8)])] self.objects += [Object(20, [(5, 10, 10)])] self.objects += [Object(30, [(6, 3, 3)])] im.set(0) # clear image for obj in self.objects: obj.insert(im) self.NaN = float("NaN") im.set(3, 7, self.NaN) im.set(0, 0, self.NaN) im.set(8, 2, self.NaN) im.set(9, 6, self.NaN) # connects the two objects with value==20 together if NaN is detected if False and display: ds9.mtv(im, frame=0)
def doSetUp(self, dwidth=0, dheight=0, x0=0, y0=0): width, height = 14 + x0 + dwidth, 10 + y0 + dheight self.im = afwImage.MaskedImageF(afwGeom.Extent2I(width, height)) # # Objects that we should detect # self.objects, self.peaks = [], [] self.objects.append([[4, 1, 10], [3, 2, 10], [4, 2, 20], [5, 2, 10], [4, 3, 10],]) self.peaks.append([[4, 2]]) self.objects.append([[9, 7, 30], [10, 7, 29], [12, 7, 25], [10, 8, 27], [11, 8, 26],]) self.peaks.append([[9, 7]]) self.objects.append([[3, 8, 10], [4, 8, 10],]) self.peaks.append([[3, 8], [4, 8],]) for pp in self.peaks: # allow for x0, y0 for p in pp: p[0] += x0 p[1] += y0 for oo in self.objects: for o in oo: o[0] += x0 o[1] += y0 self.im.set((0, 0x0, 0)) # clear image for obj in self.objects: for x, y, I in obj: self.im.getImage().set(x, y, I) if False and display: ds9.mtv(self.im, frame=0)
def measure(footprintSet, exposure): """Measure a set of Footprints, returning a SourceCatalog""" config = measAlg.SourceMeasurementConfig() config.prefix = "initial." config.algorithms.names = ["flags.pixel", "flux.psf", "flux.sinc", "flux.gaussian", "shape.sdss"] config.centroider.name = "centroid.sdss" config.algorithms["flux.naive"].radius = 3.0 config.slots.centroid = "initial.centroid.sdss" config.slots.psfFlux = "initial.flux.psf" config.slots.apFlux = "initial.flux.sinc" config.slots.modelFlux = None config.slots.instFlux = None config.slots.calibFlux = None config.slots.shape = "initial.shape.sdss" schema = afwTable.SourceTable.makeMinimalSchema() measureSources = config.makeMeasureSources(schema) catalog = afwTable.SourceCatalog(schema) config.slots.setupTable(catalog.table) if display: ds9.mtv(exposure, title="Original", frame=0) footprintSet.makeSources(catalog) for i, source in enumerate(catalog): measureSources.applyWithPeak(source, exposure) return catalog
def main(rootDir, visit, ccd, frame=1, title="", scale="zscale", zoom="to fit", trans=60, useEllipse=False): # butler を開き読み込みたいデータの dataId を指定する butler = dafPersist.Butler(rootDir) dataId = {'visit': visit, 'ccd':ccd} # butler から一次処理済データを読み込む exposure = butler.get('calexp', dataId) # 読み込みたい天体情報を設定し、ds9.mtv() を読み込む settings = {'scale':scale, 'zoom': zoom, 'mask' : 'transparency %d' %(trans)} ds9.mtv(exposure, frame=frame, title=title, settings=settings) # 天体カタログを取得し、データ点を重ねて表示する sources = butler.get('src', dataId) with ds9.Buffering(): for i,source in enumerate(sources): color = ds9.RED size = 5.0 if useEllipse: # 楕円体のシンボルで表示 symbol = "@:{ixx},{ixy},{iyy}".format(ixx=source.getIxx(), ixy=source.getIxy(), iyy=source.getIyy()) else: # シンプルなシンボルで表示(例えば、 +, x, *, o が使える) symbol = "o" ds9.dot(symbol, source.getX(), source.getY(), ctype=color, size=size, frame=frame, silent=True)
def setUp(self): self.im = afwImage.DecoratedImageD(InputSmallImagePath) self.wcs = afwImage.makeWcs(self.im.getMetadata()) if False: ds9.mtv(self.im, wcs=self.wcs)
def testStatsZebra(self): """Add 1 to every other row""" image2 = self.image.Factory(self.image, True) # # Add 1 to every other row, so the variance is 1/4 # self.assertEqual(image2.getHeight()%2, 0) width = image2.getWidth() for y in range(1, image2.getHeight(), 2): sim = image2.Factory(image2, afwGeom.Box2I(afwGeom.Point2I(0, y), afwGeom.Extent2I(width, 1)), afwImage.LOCAL) sim += 1 if display: ds9.mtv(self.image, frame = 0) ds9.mtv(image2, frame = 1) stats = afwMath.makeStatistics(image2, afwMath.NPOINT | afwMath.STDEV | afwMath.MEAN | afwMath.ERRORS) mean = stats.getResult(afwMath.MEAN) n = stats.getValue(afwMath.NPOINT) sd = stats.getValue(afwMath.STDEV) self.assertEqual(mean[0], image2.get(0, 0) + 0.5) self.assertEqual(sd, 1/math.sqrt(4.0)*math.sqrt(n/(n - 1))) self.assertAlmostEqual(mean[1], sd/math.sqrt(image2.getWidth()*image2.getHeight()), 10) meanSquare = afwMath.makeStatistics(image2, afwMath.MEANSQUARE).getValue() self.assertEqual(meanSquare, 0.5*(image2.get(0, 0)**2 + image2.get(0, 1)**2))
def setUp(self): im = afwImage.ImageF(self.monetFile("small.fits")) self.mi = afwImage.MaskedImageF(im, afwImage.MaskU(im.getDimensions()), afwImage.ImageF(im.getDimensions())); self.ds = afwDetection.FootprintSet(self.mi, afwDetection.Threshold(100)) if display: ds9.mtv(self.mi.getImage()) ds9.erase() for foot in self.ds.getFootprints(): bbox = foot.getBBox() x0, y0 = bbox.getMinX(), bbox.getMinY() x1, y1 = bbox.getMaxX(), bbox.getMaxY() xc = (x0 + x1)/2.0 yc = (y0 + y1)/2.0 if display: ds9.dot("+", xc, yc, ctype=ds9.BLUE) if False: x0 -= 0.5; y0 -= 0.5 x1 += 0.5; y1 += 0.5 ds9.line([(x0, y0), (x1, y0), (x1, y1), (x0, y1), (x0, y0)], ctype=ds9.RED) self.control = algorithms.GaussianCentroidControl() schema = afwTable.SourceTable.makeMinimalSchema() self.centroider = algorithms.MeasureSourcesBuilder().addAlgorithm(self.control).build(schema) self.ssMeasured = afwTable.SourceCatalog(schema) self.ssMeasured.table.defineCentroid(self.control.name) self.ssTruth = afwTable.SourceCatalog(schema) self.readTruth(self.monetFile("positions.dat-original"))
def testDrawing(self): """Test drawing lines and glyphs""" ds9.erase() exp = afwImage.ExposureF(300, 350) ds9.mtv(exp, title="parent") # tells display0 about the image's xy0 with ds9.Buffering(): ds9.dot('o', 200, 220) vertices = [(200, 220), (210, 230), (224, 230), (214, 220), (200, 220)] ds9.line(vertices, ctype=ds9.CYAN) ds9.line(vertices[:-1], symbs="+x+x", size=3)
def measure(self, footprintSet, exposure): """Measure a set of Footprints, returning a SourceCatalog""" table = afwTable.SourceCatalog(self.schema) footprintSet.makeSources(table) # Then run the default SFM task. Results not checked self.measureTask.run(table, exposure) if display: ds9.mtv(exposure) return table
def testKernel(self): """Test the creation of the dgPsf's kernel.""" for psf in [self.psfDg, self.psfSg]: kIm = afwImage.ImageD(psf.getKernel().getDimensions()) psf.getKernel().computeImage(kIm, False) self.assertEqual(kIm.getWidth(), self.ksize) self.assertAlmostEqual( afwMath.makeStatistics(kIm, afwMath.SUM).getValue(), 1.0) if False: ds9.mtv(kIm)
def testText(self): """Test drawing text""" ds9.erase() exp = afwImage.ExposureF(300, 350) ds9.mtv(exp, title="parent") # tells display0 about the image's xy0 with ds9.Buffering(): ds9.dot('hello', 200, 200) ds9.dot('hello', 200, 210, size=1.25) ds9.dot('hello', 200, 220, size=3, fontFamily="times") ds9.dot('hello', 200, 230, fontFamily="helvetica bold italic")
def runBasicTest(self, kernel, convControl, refKernel=None, kernelDescr="", rtol=1.0e-05, atol=1e-08): """Assert that afwMath::convolve gives the same result as reference convolution for a given kernel. Inputs: - kernel: convolution kernel - convControl: convolution control parameters (afwMath.ConvolutionControl) - refKernel: kernel to use for refConvolve (if None then kernel is used) - kernelDescr: description of kernel - rtol: relative tolerance (see below) - atol: absolute tolerance (see below) rtol and atol are positive, typically very small numbers. The relative difference (rtol * abs(b)) and the absolute difference "atol" are added together to compare against the absolute difference between "a" and "b". """ if refKernel is None: refKernel = kernel # strip garbage characters (whitespace and punctuation) to make a short description for saving files shortKernelDescr = self._removeGarbageChars(kernelDescr) doNormalize = convControl.getDoNormalize() doCopyEdge = convControl.getDoCopyEdge() maxInterpDist = convControl.getMaxInterpolationDistance() imMaskVar = self.maskedImage.getArrays() xy0 = self.maskedImage.getXY0() refCnvImMaskVarArr = refConvolve(imMaskVar, xy0, refKernel, doNormalize, doCopyEdge) refMaskedImage = afwImage.makeMaskedImageFromArrays(*refCnvImMaskVarArr) afwMath.convolve(self.cnvImage, self.maskedImage.getImage(), kernel, convControl) self.assertEqual(self.cnvImage.getXY0(), self.xy0) afwMath.convolve(self.cnvMaskedImage, self.maskedImage, kernel, convControl) if display and False: ds9.mtv(displayUtils.Mosaic().makeMosaic([ self.maskedImage, refMaskedImage, self.cnvMaskedImage]), frame=0) if False: for (x, y) in ((0, 0), (1, 0), (0, 1), (50, 50)): print("Mask(%d,%d) 0x%x 0x%x" % (x, y, refMaskedImage.getMask().get(x, y), self.cnvMaskedImage.getMask().get(x, y))) self.assertImagesNearlyEqual(self.cnvImage, refMaskedImage.getImage(), atol=atol, rtol=rtol) self.assertMaskedImagesNearlyEqual(self.cnvMaskedImage, refMaskedImage, atol=atol, rtol=rtol) if not sameMaskPlaneDicts(self.cnvMaskedImage, self.maskedImage): self.cnvMaskedImage.writeFits("act%s" % (shortKernelDescr,)) refMaskedImage.writeFits("des%s" % (shortKernelDescr,)) self.fail("convolve(MaskedImage, kernel=%s, doNormalize=%s, " "doCopyEdge=%s, maxInterpDist=%s) failed:\n%s" % (kernelDescr, doNormalize, doCopyEdge, maxInterpDist, "convolved mask dictionary does not match input"))
def testNormalize(self): """Test Footprint.normalize""" w, h = 12, 10 region = afwGeom.Box2I(afwGeom.Point2I(0, 0), afwGeom.Extent2I(w, h)) im = afwImage.ImageU(afwGeom.Extent2I(w, h)) im.set(0) # # Create a footprint; note that these Spans overlap # for spans, box in (([ (3, 5, 6), (4, 7, 7), ], afwGeom.Box2I(afwGeom.Point2I(5, 3), afwGeom.Point2I(7, 4))), ([ (3, 3, 5), (3, 6, 9), (4, 2, 3), (4, 5, 7), (4, 8, 8), (5, 2, 3), (5, 5, 8), (5, 6, 7), (6, 3, 5), ], afwGeom.Box2I(afwGeom.Point2I(2, 3), afwGeom.Point2I(9, 6)))): foot = afwDetect.Footprint(0, region) for y, x0, x1 in spans: foot.addSpan(y, x0, x1) for x in range(x0, x1 + 1): # also insert into im im.set(x, y, 1) idImage = afwImage.ImageU(afwGeom.Extent2I(w, h)) idImage.set(0) foot.insertIntoImage(idImage, 1) if display: # overlaping pixels will be > 1 ds9.mtv(idImage) # # Normalise the Footprint, removing overlapping spans # foot.normalize() idImage.set(0) foot.insertIntoImage(idImage, 1) if display: ds9.mtv(idImage, frame=1) idImage -= im self.assertTrue(box == foot.getBBox()) self.assertEqual( afwMath.makeStatistics(idImage, afwMath.MAX).getValue(), 0)
def testFootprintsMeasure(self): """Check that we can measure the objects in a detectionSet""" xcentroid = [10.0, 14.0, 9.0] ycentroid = [8.0, 11.5061728, 14.0] flux = [51.0, 101.0, 20.0] ds = afwDetection.FootprintSet(self.mi, afwDetection.Threshold(10), "DETECTED") if display: ds9.mtv(self.mi, frame=0) ds9.mtv(self.mi.getVariance(), frame=1) measureSourcesConfig = measBase.SingleFrameMeasurementConfig() measureSourcesConfig.algorithms["base_CircularApertureFlux"].radii = [3.0] measureSourcesConfig.algorithms.names = ["base_NaiveCentroid", "base_SdssShape", "base_PsfFlux", "base_CircularApertureFlux"] measureSourcesConfig.slots.centroid = "base_NaiveCentroid" measureSourcesConfig.slots.psfFlux = "base_PsfFlux" measureSourcesConfig.slots.apFlux = "base_CircularApertureFlux_3_0" measureSourcesConfig.slots.modelFlux = None measureSourcesConfig.slots.instFlux = None measureSourcesConfig.slots.calibFlux = None schema = afwTable.SourceTable.makeMinimalSchema() task = measBase.SingleFrameMeasurementTask(schema, config=measureSourcesConfig) measCat = afwTable.SourceCatalog(schema) # now run the SFM task with the test plugin sigma = 1e-10 psf = algorithms.DoubleGaussianPsf(11, 11, sigma) # i.e. a single pixel self.exposure.setPsf(psf) task.run(measCat, self.exposure) for i, source in enumerate(measCat): xc, yc = source.getX() - self.mi.getX0(), source.getY() - self.mi.getY0() if display: ds9.dot("+", xc, yc) self.assertAlmostEqual(source.getX(), xcentroid[i], 6) self.assertAlmostEqual(source.getY(), ycentroid[i], 6) self.assertEqual(source.getApFlux(), flux[i]) # 29 pixels in 3pixel circular ap. self.assertAlmostEqual(source.getApFluxErr(), math.sqrt(29), 6) # We're using a delta-function PSF, so the psfFlux should be the pixel under the centroid, # iff the object's centred in the pixel if xc == int(xc) and yc == int(yc): self.assertAlmostEqual(source.getPsfFlux(), self.exposure.getMaskedImage().getImage().get(int(xc + 0.5), int(yc + 0.5))) self.assertAlmostEqual(source.getPsfFluxErr(), self.exposure.getMaskedImage().getVariance().get(int(xc + 0.5), int(yc + 0.5)))
def testImageSliceFromBox(self): """Test using a Box2I to index an Image""" im = afwImage.ImageF(10, 20) bbox = afwGeom.BoxI(afwGeom.PointI(1, 3), afwGeom.PointI(6, 9)) im[bbox] = -1 if display: ds9.mtv(im) self.assertEqual(im.get(0, 6), 0) self.assertEqual(im.get(1, 6), -1) self.assertEqual(im.get(3, 9), -1)
def writeDefects(self, maskFile, ccd, format=None): """Given a Mask, find the defects for each amp in the specified CCD (0-indexed). If format is provided, it's expected to be used as "format % (ccd, amp)" to generate a .paf filename to write the defects too. If it's "-", write to stdout""" # Metadata should have validity range keywords, but it doesn't. if False: metaData = afwImage.readMetadata(maskFile, 0) hdu = ccd + 2 im = afwImage.ImageF(maskFile, hdu) im -= 1 im *= -1 mask = afwImage.MaskU(im.getBBox(afwImage.PARENT)) mask.set(0x0) mask = afwImage.makeMaskedImage(im, mask) for amp in self.ampList(): subMask = mask.Factory(mask, self.getTrimSecBBox(amp), afwImage.LOCAL) ds = afwDetection.makeFootprintSet(subMask, afwDetection.Threshold(0.5), "INTRP") if False: ds9.setDefaultFrame(amp) ds9.mtv(subMask) ds9.dot("Amp %d" % amp, 0, 0) if not format: return if format == "-": fd = sys.stdout else: fd = open(format % (ccd, amp), "w") print >> fd, """\ #<?cfg paf policy ?> # # Defects for CCD%03d amp %02d generated from %s, HDU %d # # Coordinates are trimmed and per-amp not per-CCD. If you change this, the ISR will have to change # # Generated by $HeadURL$ # """ % (ccd, amp, maskFile, hdu), for foot in ds.getFootprints(): afwDetectionUtils.writeFootprintAsDefects(fd, foot)
def run(display=False): exposure = loadData() schema = afwTable.SourceTable.makeMinimalSchema() # # Create the detection task # config = SourceDetectionTask.ConfigClass() config.thresholdPolarity = "both" config.background.isNanSafe = True config.thresholdValue = 3 detectionTask = SourceDetectionTask(config=config, schema=schema) # # And the measurement Task # config = SingleFrameMeasurementTask.ConfigClass() config.algorithms.names = ["base_SdssCentroid", "base_SdssShape", "base_CircularApertureFlux"] config.algorithms["base_CircularApertureFlux"].radii = [1, 2, 4, 8, 16] # pixels config.slots.instFlux = None config.slots.modelFlux = None config.slots.psfFlux = None algMetadata = dafBase.PropertyList() measureTask = SingleFrameMeasurementTask(schema, algMetadata=algMetadata, config=config) radii = algMetadata.get("base_CircularApertureFlux_radii") # # Create the output table # tab = afwTable.SourceTable.make(schema) # # Process the data # result = detectionTask.run(tab, exposure) sources = result.sources print("Found %d sources (%d +ve, %d -ve)" % (len(sources), result.fpSets.numPos, result.fpSets.numNeg)) measureTask.run(sources, exposure) if display: # display on ds9 (see also --debug argparse option) frame = 1 ds9.mtv(exposure, frame=frame) with ds9.Buffering(): for s in sources: xy = s.getCentroid() ds9.dot('+', *xy, ctype=ds9.CYAN if s.get("flags.negative") else ds9.GREEN, frame=frame) ds9.dot(s.getShape(), *xy, ctype=ds9.RED, frame=frame) for i in range(s.get("flux.aperture.nProfile")): ds9.dot('o', *xy, size=radii[i], ctype=ds9.YELLOW, frame=frame)
def selectStars(self, exposure, sourceCat, matches=None): """!Return a list of PSF candidates that represent likely stars A list of PSF candidates may be used by a PSF fitter to construct a PSF. @param[in] exposure the exposure containing the sources @param[in] sourceCat catalog of sources that may be stars (an lsst.afw.table.SourceCatalog) @param[in] matches a match vector as produced by meas_astrom; required (defaults to None to match the StarSelector API and improve error handling) @return an lsst.pipe.base.Struct containing: - starCat catalog of selected stars (a subset of sourceCat) """ import lsstDebug debugInfo = lsstDebug.Info(__name__) display = debugInfo.display pauseAtEnd = debugInfo.pauseAtEnd # pause when done if matches is None: raise RuntimeError("CatalogStarSelectorTask requires matches") mi = exposure.getMaskedImage() if display: frame = 1 ds9.mtv(mi, frame=frame, title="PSF candidates") isGoodSource = CheckSource(sourceCat, self.config.fluxLim, self.config.fluxMax, self.config.badFlags) starCat = SourceCatalog(sourceCat.schema) with ds9.Buffering(): for ref, source, d in matches: if not ref.get("resolved"): if not isGoodSource(source): symb, ctype = "+", ds9.RED else: starCat.append(source) symb, ctype = "+", ds9.GREEN if display: ds9.dot(symb, source.getX() - mi.getX0(), source.getY() - mi.getY0(), size=4, frame=frame, ctype=ctype) if display and pauseAtEnd: input("Continue? y[es] p[db] ") return Struct(starCat=starCat, )
def testFlip(self): """Test that we end up with the correct image after flipping it""" frame = 2 for flipLR, flipTB, x, y in [(True, False, 19, 0), (True, True, 19, 9), (False, True, 0, 9), (False, False, 0, 0)]: outImage = afwMath.flipImage(self.inImage, flipLR, flipTB) if display: ds9.mtv(outImage, frame=frame, title="%s %s" % (flipLR, flipTB)) frame += 1 self.assertEqual(self.inImage.get(0, 0), outImage.get(x, y))
def testImageSliceFromBoxOrigin(self): """Test using a Box2I to index an Image""" im = afwImage.ImageF(10, 20) im.setXY0(50, 100) bbox = afwGeom.BoxI(afwGeom.PointI(51, 103), afwGeom.ExtentI(6, 7)) im[bbox, afwImage.PARENT] = -1 if display: ds9.mtv(im) self.assertEqual(im.get(0, 6), 0) self.assertEqual(im.get(1, 6), -1) self.assertEqual(im.get(3, 9), -1)
def testFootprintSetImageId(self): """Check that we can insert a FootprintSet into an Image, setting relative IDs""" ds = afwDetect.FootprintSet(self.ms, afwDetect.Threshold(10)) objects = ds.getFootprints() idImage = ds.insertIntoImage(True) if display: ds9.mtv(idImage, frame=2) for i in range(len(objects)): for sp in objects[i].getSpans(): for x in range(sp.getX0(), sp.getX1() + 1): self.assertEqual(idImage.get(x, sp.getY()), i + 1)
def testComputeImage(self): """Test the computation of the PSF's image at a point""" ccdXY = afwGeom.Point2D(0, 0) kIm = self.psf.computeImage(ccdXY) if False: ds9.mtv(kIm) self.assertTrue(kIm.getWidth() == self.ksize) xcen, ycen = self.ksize/2, self.ksize/2 kIm = self.psf.computeImage(ccdXY) self.assertAlmostEqual(afwMath.makeStatistics(kIm, afwMath.SUM).getValue(), 1.0)
def OpenTimepixInDS9(filename, binary=False): import lsst.afw.display.ds9 as ds9 if binary: image, dummy = TimepixToExposure_binary(filename, 0, 255, 0, 255) else: image = TimepixToExposure(filename, 0, 255, 0, 255) try: ds9.initDS9(False) except ds9.Ds9Error: print('DS9 launch bug error thrown away (probably)') ds9.mtv(image)
def testImageSliceFromBoxOrigin(self): """Test using a Box2I to index an Image""" im = afwImage.ImageF(10, 20) im.setXY0(50, 100) bbox = lsst.geom.BoxI(lsst.geom.PointI(51, 103), lsst.geom.ExtentI(6, 7)) im[bbox] = -1 if display: ds9.mtv(im) self.assertEqual(im[0, 6, afwImage.LOCAL], 0) self.assertEqual(im[1, 6, afwImage.LOCAL], -1) self.assertEqual(im[3, 9, afwImage.LOCAL], -1)
def testFootprints(self): """Check that we found the correct number of objects using FootprintSet""" ds = afwDetect.FootprintSet(self.ms, afwDetect.Threshold(10), "DETECTED") objects = ds.getFootprints() if display: ds9.mtv(self.ms, frame=0) self.assertEqual(len(objects), len(self.objects)) for i in range(len(objects)): self.assertEqual(objects[i], self.objects[i])
def fft(im1, im2, fftSize): arr1 = im1.getArray() arr2 = im2.getArray() fft1 = num.fft.rfft2(arr1) fft2 = num.fft.rfft2(arr2) rat = fft2 / fft1 kfft = num.fft.irfft2(rat, s=fftSize) kim = afwImage.ImageF(fftSize) kim.getArray()[:] = kfft ds9.mtv(kim, frame=5)
def showPeaks(im=None, fs=None, frame=0): """Show the image and peaks""" if frame is None: return if im: ds9.mtv(im, frame=frame) if fs: with ds9.Buffering(): # turn on buffering of ds9's slow "region" writes for foot in fs.getFootprints(): for p in foot.getPeaks(): ds9.dot("+", p.getIx(), p.getIy(), size=0.4, ctype=ds9.RED, frame=frame)
def testFootprintsMasks(self): """Check that detectionSets have the proper mask bits set""" ds = afwDetect.FootprintSet(self.ms, afwDetect.Threshold(10), "OBJECT") objects = ds.getFootprints() if display: ds9.mtv(self.ms, frame=1) mask = self.ms.getMask() for i in range(len(objects)): for sp in objects[i].getSpans(): for x in range(sp.getX0(), sp.getX1() + 1): self.assertEqual(mask.get(x, sp.getY()), mask.getPlaneBitMask("OBJECT"))
def testGrow(self): """Test growing a footprint""" x0, y0 = 20, 20 width, height = 20, 30 foot1 = afwDetect.Footprint( afwGeom.Box2I(afwGeom.Point2I(x0, y0), afwGeom.Extent2I(width, height)), afwGeom.Box2I(afwGeom.Point2I(0, 0), afwGeom.Extent2I(100, 100))) bbox1 = foot1.getBBox() self.assertEqual(bbox1.getMinX(), x0) self.assertEqual(bbox1.getMaxX(), x0 + width - 1) self.assertEqual(bbox1.getWidth(), width) self.assertEqual(bbox1.getMinY(), y0) self.assertEqual(bbox1.getMaxY(), y0 + height - 1) self.assertEqual(bbox1.getHeight(), height) ngrow = 5 for isotropic in (True, False): foot2 = afwDetect.growFootprint(foot1, ngrow, isotropic) # Check that the grown footprint is normalized self.assertTrue(foot2.isNormalized()) # Check that the grown footprint is bigger than the original self.assertGreater(foot2.getArea(), foot1.getArea()) bbox2 = foot2.getBBox() if False and display: idImage = afwImage.ImageU(width, height) idImage.set(0) i = 1 for foot in [foot1, foot2]: foot.insertIntoImage(idImage, i) i += 1 metricImage = afwImage.ImageF("foo.fits") ds9.mtv(metricImage, frame=1) ds9.mtv(idImage) # check bbox2 self.assertEqual(bbox2.getMinX(), x0 - ngrow) self.assertEqual(bbox2.getWidth(), width + 2 * ngrow) self.assertEqual(bbox2.getMinY(), y0 - ngrow) self.assertEqual(bbox2.getHeight(), height + 2 * ngrow) # Check that region was preserved self.assertEqual(foot1.getRegion(), foot2.getRegion())
def getBackground(image, backgroundConfig, nx=0, ny=0, algorithm=None): """ Make a new Exposure which is exposure - background """ backgroundConfig.validate() if not nx: nx = image.getWidth() // backgroundConfig.binSize + 1 if not ny: ny = image.getHeight() // backgroundConfig.binSize + 1 displayBackground = lsstDebug.Info(__name__).displayBackground if displayBackground: import itertools ds9.mtv(image, frame=1) xPosts = numpy.rint( numpy.linspace(0, image.getWidth() + 1, num=nx, endpoint=True)) yPosts = numpy.rint( numpy.linspace(0, image.getHeight() + 1, num=ny, endpoint=True)) with ds9.Buffering(): for (xMin, xMax), (yMin, yMax) in itertools.product( zip(xPosts[:-1], xPosts[1:]), zip(yPosts[:-1], yPosts[1:])): ds9.line([(xMin, yMin), (xMin, yMax), (xMax, yMax), (xMax, yMin), (xMin, yMin)], frame=1) sctrl = afwMath.StatisticsControl() sctrl.setAndMask( reduce(lambda x, y: x | image.getMask().getPlaneBitMask(y), backgroundConfig.ignoredPixelMask, 0x0)) sctrl.setNanSafe(backgroundConfig.isNanSafe) pl = pexLogging.Debug("meas.utils.sourceDetection.getBackground") pl.debug( 3, "Ignoring mask planes: %s" % ", ".join(backgroundConfig.ignoredPixelMask)) if not algorithm: algorithm = backgroundConfig.algorithm bctrl = afwMath.BackgroundControl(algorithm, nx, ny, backgroundConfig.undersampleStyle, sctrl, backgroundConfig.statisticsProperty) if backgroundConfig.useApprox: actrl = afwMath.ApproximateControl( afwMath.ApproximateControl.CHEBYSHEV, backgroundConfig.approxOrder) bctrl.setApproximateControl(actrl) return afwMath.makeBackground(image, bctrl)
def setUp(self): # We create an image that has a ramp (unique values for each pixel), # with a single high pixel that allows for centering self.width, self.height = 50, 50 self.xcen, self.ycen = self.width // 2, self.height // 2 self.image = afwImage.ImageF(afwGeom.ExtentI(self.width, self.height)) for y in range(self.height): for x in range(self.width): self.image.set(x, y, self.width * y + x) self.image.set(self.xcen, self.ycen, 1234567.89) self.exp = afwImage.makeExposure(afwImage.makeMaskedImage(self.image)) self.exp.getMaskedImage().getVariance().set(1.0) scale = 0.2 / 3600 wcs = afwImage.makeWcs( afwCoord.Coord(0 * afwGeom.degrees, 0 * afwGeom.degrees), afwGeom.Point2D(self.xcen, self.ycen), scale, 0, 0, scale) self.exp.setWcs(wcs) if display: frame = 1 ds9.mtv(self.exp, frame=frame, title="Single pixel") # We will use a GaussianCentroid to tweak the center (it should not, for forced measurement) # and a NaiveFlux to measure the single pixel. We'll start offset from the high pixel, # so that a forced measurement should yield a flux of zero, while a measurement that was allowed to # center should yield a flux of unity. # Note that previous versions used NaiveCentroid, which was so nonrobust that it failed to get # right answer when the input value was round-tripped through Wcs and modified by ~1E-8. gaussianCentroid = measAlg.GaussianCentroidControl() naiveFlux = measAlg.NaiveFluxControl() naiveFlux.radius = 0.5 self.x, self.y = self.xcen - 1, self.ycen - 1 self.foot = afwDetection.Footprint(afwGeom.Point2I(self.x, self.y), 2) self.foot.addPeak(self.x, self.y, float("NaN")) schema = afwTable.SourceTable.makeMinimalSchema() msb = measAlg.MeasureSourcesBuilder() msb.addAlgorithm(naiveFlux) msb.setCentroider(gaussianCentroid) self.measurer = msb.build(schema) self.table = afwTable.SourceTable.make(schema) self.table.defineCentroid("centroid.gaussian") schemaF = afwTable.SourceTable.makeMinimalSchema() msbF = measAlg.MeasureSourcesBuilder("", True) msbF.addAlgorithm(naiveFlux) msbF.setCentroider(gaussianCentroid) self.measurerF = msbF.build(schemaF) self.tableF = afwTable.SourceTable.make(schemaF) self.tableF.defineCentroid("centroid.gaussian")
def testOffsetGaussian(self): """Insert a Gaussian, offset, and check the residuals""" size = 50 refIm = afwImage.ImageF(size, size) unshiftedIm = afwImage.ImageF(size, size) xc, yc = size/2.0, size/2.0 amp, sigma1 = 1.0, 3 # # Calculate Gaussian directly at (xc, yc) # self.calcGaussian(refIm, xc, yc, amp, sigma1) for dx in (-55.5, -1.500001, -1.5, -1.499999, -1.00001, -1.0, -0.99999, -0.5, 0.0, 0.5, 0.99999, 1.0, 1.00001, 1.499999, 1.5, 1.500001, 99.3): for dy in (-3.7, -1.500001, -1.5, -1.499999, -1.00001, -1.0, -0.99999, -0.5, 0.0, 0.5, 0.99999, 1.0, 1.00001, 1.499999, 1.5, 1.500001, 2.99999): dOrigX, dOrigY, dFracX, dFracY = getOrigFracShift(dx, dy) self.calcGaussian(unshiftedIm, xc - dFracX, yc - dFracY, amp, sigma1) for algorithm, maxMean, maxLim in ( ("lanczos5", 1e-8, 0.0015), ("bilinear", 1e-8, 0.03), ("nearest", 1e-8, 0.2), ): im = afwImage.ImageF(size, size) im = afwMath.offsetImage(unshiftedIm, dx, dy, algorithm) if display: ds9.mtv(im, frame=0) im -= refIm if display: ds9.mtv(im, frame=1) imArr = im.getArray() imGoodVals = np.ma.array(imArr, copy=False, mask=np.isnan(imArr)).compressed() try: imXY0 = tuple(im.getXY0()) self.assertEqual(imXY0, (dOrigX, dOrigY)) self.assertLess(abs(imGoodVals.mean()), maxMean*amp) self.assertLess(abs(imGoodVals.max()), maxLim*amp) self.assertLess(abs(imGoodVals.min()), maxLim*amp) except: print("failed on algorithm=%s; dx = %s; dy = %s" % (algorithm, dx, dy)) raise
def main(rootDir, visit, ccd, frame=1, title="", scale="zscale", zoom="to fit", trans=60, useEllipse=False): # butler を開き読み込みたいデータの dataId を指定する butler = dafPersist.Butler(rootDir) dataId = {'visit': visit, 'ccd': ccd} # butler から一次処理済データを読み込む exposure = butler.get('calexp', dataId) # 読み込みたい天体情報を設定し、ds9.mtv() を読み込む settings = { 'scale': scale, 'zoom': zoom, 'mask': 'transparency %d' % (trans) } ds9.mtv(exposure, frame=frame, title=title, settings=settings) # 天体カタログを取得し、データ点を重ねて表示する sources = butler.get('src', dataId) with ds9.Buffering(): for i, source in enumerate(sources): color = ds9.RED size = 5.0 if useEllipse: # 楕円体のシンボルで表示 symbol = "@:{ixx},{ixy},{iyy}".format(ixx=source.getIxx(), ixy=source.getIxy(), iyy=source.getIyy()) else: # シンプルなシンボルで表示(例えば、 +, x, *, o が使える) symbol = "o" ds9.dot(symbol, source.getX(), source.getY(), ctype=color, size=size, frame=frame, silent=True)
def testImage(self): """Test Polygon.createImage""" for i, num in enumerate(range(3, 30)): poly = self.polygon(num, 25, 75, 75) box = afwGeom.Box2I(afwGeom.Point2I(15, 15), afwGeom.Extent2I(115, 115)) image = poly.createImage(box) if DEBUG: import lsst.afw.display.ds9 as ds9 ds9.mtv(image, frame=i + 1, title="Polygon nside=%d" % num) for p1, p2 in poly.getEdges(): ds9.line((p1, p2), frame=i + 1) self.assertAlmostEqual( image.getArray().sum() / poly.calculateArea(), 1.0, 6)
def testTwoDisplays(self): """Test that we can do things with two frames""" exp = afwImage.ExposureF(300, 350) for frame in (0, 1): ds9.setMaskTransparency(50, frame=frame) if frame == 1: ds9.setMaskPlaneColor("CROSSTALK", "ignore", frame=frame) ds9.mtv(exp, title="parent", frame=frame) ds9.erase(frame=frame) ds9.dot('o', 205, 180, size=6, ctype=ds9.RED, frame=frame)
def testComputeImage(self): """Test the computation of the PSF's image at a point.""" for psf in [self.psfDg, self.psfSg]: ccdXY = afwGeom.Point2D(0, 0) kIm = psf.computeImage(ccdXY) if False: ds9.mtv(kIm) self.assertEqual(kIm.getWidth(), self.ksize) kIm = psf.computeImage(ccdXY) self.assertAlmostEqual( afwMath.makeStatistics(kIm, afwMath.SUM).getValue(), 1.0)
def testTicket1040(self): """ How to repeat from #1040""" image = afwImage.ImageD(afwGeom.Extent2I(6, 6)) image.set(2, 2, 100) bbox = afwGeom.Box2I(afwGeom.Point2I(1, 1), afwGeom.Extent2I(5, 5)) subImage = image.Factory(image, bbox) subImageF = subImage.convertFloat() if display: ds9.mtv(subImage, frame=0, title="subImage") ds9.mtv(subImageF, frame=1, title="converted subImage") self.assertEqual(subImage.get(1, 1), subImageF.get(1, 1))