def testDefaultSize(self): """Test of both default size and specified size.""" print("DefaultSizeTest") sigma0 = 5 # set the peak of the outer guassian to 0 so this is really a single gaussian. psf = measAlg.DoubleGaussianPsf(60, 60, 1.5 * sigma0, 1, 0.0) # Now make the catalog record = self.mycatalog.getTable().makeRecord() psf = measAlg.DoubleGaussianPsf(100, 100, 10.0, 1.00, 1.0) record.setPsf(psf) wcs = afwGeom.makeSkyWcs(crpix=self.crpix, crval=self.crval, cdMatrix=self.cdMatrix) record.setWcs(wcs) record['weight'] = 1.0 record['id'] = 1 bbox = lsst.geom.Box2I(lsst.geom.Point2I(0, 0), lsst.geom.Extent2I(2000, 2000)) record.setBBox(bbox) self.mycatalog.append(record) mypsf = measAlg.CoaddPsf(self.mycatalog, self.wcsref) # , 'weight') m1coadd, m2coadd = getCoaddSecondMoments(mypsf, lsst.geom.Point2D(0, 0)) m1, m2 = getPsfSecondMoments(mypsf, lsst.geom.Point2D(1000, 1000)) self.assertAlmostEqual(m1, m1coadd, delta=.01) self.assertAlmostEqual(m2, m2coadd, delta=.01)
def generateFakeImages(): tSigma = 1.5 tMi, sMi, sK, kcs, confake = diffimTools.makeFakeKernelSet(tGaussianWidth=tSigma, bgValue=200) sSigma = 2.5 tWcs = generateFakeWcs() sWcs = generateFakeWcs() tExp = afwImage.ExposureF(tMi, tWcs) sExp = afwImage.ExposureF(sMi, sWcs) tPsf = measAlg.DoubleGaussianPsf(21, 21, tSigma) sPsf = measAlg.DoubleGaussianPsf(21, 21, sSigma) tExp.setPsf(tPsf) sExp.setPsf(sPsf) return tExp, sExp
def testSimpleGaussian(self): """Check that we can measure a single Gaussian's attributes.""" print("SimpleGaussianTest") sigma0 = 5 # set the peak of the outer guassian to 0 so this is really a single gaussian. psf = measAlg.DoubleGaussianPsf(60, 60, 1.5 * sigma0, 1, 0.0) sigma = [5, 6, 7, 8] # 5 pixels is the same as a sigma of 1 arcsec. # lay down a simple pattern of four ccds, set in a pattern of 1000 pixels around the center offsets = [(1999, 1999), (1999, 0), (0, 0), (0, 1999)] # Imagine a ccd in each of positions +-1000 pixels from the center for i in range(4): record = self.mycatalog.getTable().makeRecord() psf = measAlg.DoubleGaussianPsf(100, 100, sigma[i], 1.00, 1.0) record.setPsf(psf) crpix = afwGeom.PointD(offsets[i][0], offsets[i][1]) wcs = afwImage.makeWcs(self.crval, crpix, self.cd11, self.cd12, self.cd21, self.cd22) # print out the coorinates of this supposed 2000x2000 ccd in wcsref coordinates beginCoord = wcs.pixelToSky(0, 0) endCoord = wcs.pixelToSky(2000, 2000) self.wcsref.skyToPixel(beginCoord) self.wcsref.skyToPixel(endCoord) record.setWcs(wcs) record['weight'] = 1.0 record['id'] = i bbox = afwGeom.Box2I(afwGeom.Point2I(0, 0), afwGeom.Extent2I(2000, 2000)) record.setBBox(bbox) self.mycatalog.append(record) #img = psf.computeImage(afwGeom.Point2D(1000,1000), afwGeom.Extent2I(100,100), False, False) # img.writeFits("img%d.fits"%i) mypsf = measAlg.CoaddPsf(self.mycatalog, self.wcsref) # , 'weight') m1coadd, m2coadd = getCoaddSecondMoments(mypsf, afwGeom.Point2D(1000, 1000)) m1, m2 = getPsfSecondMoments(mypsf, afwGeom.Point2D(1000, 1000)) self.assertAlmostEqual(m1, m1coadd, delta=.01) m1, m2 = getPsfSecondMoments(mypsf, afwGeom.Point2D(1000, 1001)) m1coadd, m2coadd = getCoaddSecondMoments(mypsf, afwGeom.Point2D(1000, 1001)) self.assertAlmostEqual(m1, m1coadd, delta=0.01)
def testWeight(self): """Check that we can measure a single Gaussian's attributes.""" print("WeightTest") sigma0 = 5 # set the peak of the outer guassian to 0 so this is really a single gaussian. psf = measAlg.DoubleGaussianPsf(60, 60, 1.5 * sigma0, 1, 0.0) sigma = [5, 6, 7, 8] # 5 pixels is the same as a sigma of 1 arcsec. # lay down a simple pattern of four ccds, set in a pattern of 1000 pixels around the center offsets = [(1999, 1999), (1999, 0), (0, 0), (0, 1999)] # Imagine a ccd in each of positions +-1000 pixels from the center for i in range(4): record = self.mycatalog.getTable().makeRecord() psf = measAlg.DoubleGaussianPsf(100, 100, sigma[i], 1.00, 0.0) record.setPsf(psf) crpix = lsst.geom.PointD(offsets[i][0], offsets[i][1]) wcs = afwGeom.makeSkyWcs(crpix=crpix, crval=self.crval, cdMatrix=self.cdMatrix) # print out the coorinates of this supposed 2000x2000 ccd in wcsref coordinates record.setWcs(wcs) record['weight'] = 1.0 * (i + 1) record['id'] = i bbox = lsst.geom.Box2I(lsst.geom.Point2I(0, 0), lsst.geom.Extent2I(2000, 2000)) record.setBBox(bbox) self.mycatalog.append(record) mypsf = measAlg.CoaddPsf(self.mycatalog, self.wcsref) # , 'weight') m1, m2 = getPsfSecondMoments(mypsf, lsst.geom.Point2D(1000, 1000)) m1coadd, m2coadd = getCoaddSecondMoments(mypsf, lsst.geom.Point2D(1000, 1000)) self.assertAlmostEqual(m1, m1coadd, delta=0.01) m1, m2 = getPsfSecondMoments(mypsf, lsst.geom.Point2D(1000, 1001)) m1coadd, m2coadd = getCoaddSecondMoments(mypsf, lsst.geom.Point2D(1000, 1001)) self.assertAlmostEqual(m1, m1coadd, delta=0.01) m1, m2 = getCoaddSecondMoments(mypsf, lsst.geom.Point2D(1001, 1000)) m1coadd, m2coadd = getCoaddSecondMoments(mypsf, lsst.geom.Point2D(1001, 1000)) self.assertAlmostEqual(m1, m1coadd, delta=0.01)
def _makeImage(self): self.exposure = afwImage.ExposureF(128, 128) self.exposure.setPsf(measAlg.DoubleGaussianPsf(11, 11, 2.0, 3.7)) mi = self.exposure.getMaskedImage() mi.set(0.) self.exposure.setWcs( makeWcs()) # required for PSF construction via CoaddPsf
def testTicket2872(self): """Test that CoaddPsf.getAveragePosition() is always a position at which we can call computeImage(). """ schema = afwTable.ExposureTable.makeMinimalSchema() weightKey = schema.addField("weight", type=float, doc="photometric weight") catalog = afwTable.ExposureCatalog(schema) cdelt = (0.2 * afwGeom.arcseconds).asDegrees() wcs = afwImage.makeWcs( afwCoord.IcrsCoord(afwGeom.Point2D(45.0, 45.0), afwGeom.degrees), afwGeom.Point2D(50, 50), cdelt, 0.0, 0.0, cdelt) kernel = measAlg.DoubleGaussianPsf(7, 7, 2.0).getKernel() psf1 = measAlg.KernelPsf(kernel, afwGeom.Point2D(0, 50)) psf2 = measAlg.KernelPsf(kernel, afwGeom.Point2D(100, 50)) record1 = catalog.addNew() record1.setPsf(psf1) record1.setWcs(wcs) record1.setD(weightKey, 1.0) record1.setBBox( afwGeom.Box2I(afwGeom.Point2I(-40, 0), afwGeom.Point2I(40, 100))) record2 = catalog.addNew() record2.setPsf(psf2) record2.setWcs(wcs) record2.setD(weightKey, 1.0) record2.setBBox( afwGeom.Box2I(afwGeom.Point2I(60, 0), afwGeom.Point2I(140, 100))) coaddPsf = measAlg.CoaddPsf(catalog, wcs) naiveAvgPos = afwGeom.Point2D(50, 50) self.assertRaises(pexExceptions.InvalidParameterError, coaddPsf.computeKernelImage, naiveAvgPos) # important test is that this doesn't throw: coaddPsf.computeKernelImage()
def setUp(self): self.FWHM = 5 # pixels self.size = 128 self.psf = algorithms.DoubleGaussianPsf(29, 29, self.FWHM/(2*math.sqrt(2*math.log(2)))) self.mi = afwImage.MaskedImageF(128, 128) self.mi.set((0,0,1))
def testBBox(self): """Check that we can measure a single Gaussian's attributes.""" print("BBoxTest") sigma0 = 5 size = [50, 60, 70, 80] for i in range(4): record = self.mycatalog.getTable().makeRecord() psf = measAlg.DoubleGaussianPsf(size[i], size[i], sigma0, 1.00, 0.0) record.setPsf(psf) wcs = afwImage.makeWcs(self.crval, self.crpix, self.cd11, self.cd12, self.cd21, self.cd22) record.setWcs(wcs) record['weight'] = 1.0 * (i + 1) record['id'] = i bbox = afwGeom.Box2I(afwGeom.Point2I(0, 0), afwGeom.Extent2I(2000, 2000)) record.setBBox(bbox) self.mycatalog.append(record) mypsf = measAlg.CoaddPsf(self.mycatalog, self.wcsref, 'weight') self.assertEqual(mypsf.computeKernelImage().getBBox(), mypsf.computeBBox())
def testTicket2872(self): """Test that CoaddPsf.getAveragePosition() is always a position at which we can call computeImage(). """ cdelt = (0.2 * afwGeom.arcseconds).asDegrees() wcs = afwImage.makeWcs( afwCoord.IcrsCoord(afwGeom.Point2D(45.0, 45.0), afwGeom.degrees), afwGeom.Point2D(50, 50), cdelt, 0.0, 0.0, cdelt) kernel = measAlg.DoubleGaussianPsf(7, 7, 2.0).getKernel() psf1 = measAlg.KernelPsf(kernel, afwGeom.Point2D(0, 50)) psf2 = measAlg.KernelPsf(kernel, afwGeom.Point2D(100, 50)) record1 = self.mycatalog.addNew() record1.setPsf(psf1) record1.setWcs(wcs) record1.setD(self.weightKey, 1.0) record1.setBBox( afwGeom.Box2I(afwGeom.Point2I(-40, 0), afwGeom.Point2I(40, 100))) record2 = self.mycatalog.addNew() record2.setPsf(psf2) record2.setWcs(wcs) record2.setD(self.weightKey, 1.0) record2.setBBox( afwGeom.Box2I(afwGeom.Point2I(60, 0), afwGeom.Point2I(140, 100))) coaddPsf = measAlg.CoaddPsf(self.mycatalog, wcs) naiveAvgPos = afwGeom.Point2D(50, 50) with self.assertRaises(pexExceptions.InvalidParameterError): coaddPsf.computeKernelImage(naiveAvgPos) # important test is that this doesn't throw: coaddPsf.computeKernelImage()
def testFitsPersistence(self): psf1 = algorithms.DoubleGaussianPsf(self.ksize, self.ksize, self.sigma1, self.sigma2, self.b) filename = "tests/data/psf1-1.fits" psf1.writeFits(filename) psf2 = algorithms.DoubleGaussianPsf.readFits(filename) self.comparePsfs(psf1, psf2)
def setUp(self): self.FWHM = 5 # pixels self.psf = algorithms.DoubleGaussianPsf( 29, 29, self.FWHM / (2 * math.sqrt(2 * math.log(2)))) self.mi = afwImage.MaskedImageF(imageFile0) self.XY0 = lsst.geom.PointI(0, 0) # origin of the subimage we use if imageFile0: if True: # use full image, trimmed to data section self.XY0 = lsst.geom.PointI(32, 2) self.mi = self.mi.Factory( self.mi, lsst.geom.BoxI(self.XY0, lsst.geom.PointI(2079, 4609)), afwImage.LOCAL) self.mi.setXY0(lsst.geom.PointI(0, 0)) self.nCR = 1076 # number of CRs we should detect else: # use sub-image if True: self.XY0 = lsst.geom.PointI(824, 140) self.nCR = 10 else: self.XY0 = lsst.geom.PointI(280, 2750) self.nCR = 2 self.mi = self.mi.Factory( self.mi, lsst.geom.BoxI(self.XY0, lsst.geom.ExtentI(256, 256), afwImage.LOCAL)) self.mi.setXY0(lsst.geom.PointI(0, 0)) else: self.nCR = None self.mi.getMask().addMaskPlane("DETECTED")
def setUp(self): FWHM = 5 self.ksize = 25 # size of desired kernel sigma = FWHM / (2 * math.sqrt(2 * math.log(2))) self.psfDg = measAlg.DoubleGaussianPsf(self.ksize, self.ksize, sigma, 1, 0.1) self.psfSg = measAlg.SingleGaussianPsf(self.ksize, self.ksize, sigma)
def testPadPsf(self): """Test automatic and manual PSF padding Compare expected Psf size, after padding, to the reference Psf size. The reference Psf Size is proxy for the Sciencee Psf size here. """ psfModel = measAlg.DoubleGaussianPsf(self.ksize, self.ksize, self.sigma2) # Test automatic padding (doAutoPadPsf is True by default) autoPaddedKernel = nextOddInteger(self.subconfig.kernelSize * self.config.autoPadPsfTo) psfMatch = ipDiffim.ModelPsfMatchTask(config=self.config) results = psfMatch.run(self.exp, psfModel) self.assertEqual( results.psfMatchedExposure.getPsf().computeImage().getWidth(), autoPaddedKernel) # Test manual padding self.config.doAutoPadPsf = False PAD_EVEN_VALUES = [0, 2, 4] for padPix in PAD_EVEN_VALUES: self.config.padPsfBy = padPix psfMatch = ipDiffim.ModelPsfMatchTask(config=self.config) results = psfMatch.run(self.exp, psfModel) self.assertEqual( results.psfMatchedExposure.getPsf().computeImage().getWidth(), self.ksize + padPix) PAD_ODD_VALUES = [1, 3, 5] for padPix in PAD_ODD_VALUES: self.config.padPsfBy = padPix psfMatch = ipDiffim.ModelPsfMatchTask(config=self.config) with self.assertRaises(ValueError): results = psfMatch.run(self.exp, psfModel)
def processSingle(self, sensorRef): """Process a single CCD Besides the regular ISR, also masks cosmic-rays and divides each processed image by the dark time to generate images of the dark rate. The dark time is provided by the 'getDarkTime' method. """ exposure = CalibTask.processSingle(self, sensorRef) if self.config.doRepair: psf = measAlg.DoubleGaussianPsf( self.config.psfSize, self.config.psfSize, self.config.psfFwhm / (2 * math.sqrt(2 * math.log(2)))) exposure.setPsf(psf) self.repair.run(exposure, keepCRs=False) if self.config.crGrow > 0: mask = exposure.getMaskedImage().getMask().clone() mask &= mask.getPlaneBitMask("CR") fpSet = afwDet.FootprintSet(mask, afwDet.Threshold(0.5)) fpSet = afwDet.FootprintSet(fpSet, self.config.crGrow, True) fpSet.setMask(exposure.getMaskedImage().getMask(), "CR") mi = exposure.getMaskedImage() mi /= self.getDarkTime(exposure) return exposure
def testLargeTransform(self): """Test that images with bad astrometry are identified""" multiplier = 1000.0 # CD matrix multiplier for bad input badId = 1 # ID of bad input for ii in range(3): record = self.mycatalog.addNew() record.setPsf(measAlg.DoubleGaussianPsf(50, 50, 5.0, 1.00, 0.0)) cdMatrix = self.cdMatrix if ii == badId: # This image has bad astrometry: cdMatrix *= multiplier record['id'] = ii record['weight'] = 1.0 record.setWcs( afwGeom.makeSkyWcs(crpix=self.crpix, crval=self.crval, cdMatrix=cdMatrix)) record.setBBox( lsst.geom.Box2I(lsst.geom.Point2I(0, 0), lsst.geom.Extent2I(2000, 2000))) coaddPsf = measAlg.CoaddPsf(self.mycatalog, self.wcsref) with self.assertRaises(pexExceptions.RangeError) as cm: coaddPsf.computeKernelImage() self.assertIn("id=%d" % (badId, ), str(cm.exception))
def testTicket2872(self): """Test that CoaddPsf.getAveragePosition() is always a position at which we can call computeImage(). """ scale = 0.2 * lsst.geom.arcseconds cdMatrix = afwGeom.makeCdMatrix(scale=scale) wcs = afwGeom.makeSkyWcs( crpix=lsst.geom.Point2D(50, 50), crval=lsst.geom.SpherePoint(45.0, 45.0, lsst.geom.degrees), cdMatrix=cdMatrix, ) kernel = measAlg.DoubleGaussianPsf(7, 7, 2.0).getKernel() psf1 = measAlg.KernelPsf(kernel, lsst.geom.Point2D(0, 50)) psf2 = measAlg.KernelPsf(kernel, lsst.geom.Point2D(100, 50)) record1 = self.mycatalog.addNew() record1.setPsf(psf1) record1.setWcs(wcs) record1.setD(self.weightKey, 1.0) record1.setBBox( lsst.geom.Box2I(lsst.geom.Point2I(-40, 0), lsst.geom.Point2I(40, 100))) record2 = self.mycatalog.addNew() record2.setPsf(psf2) record2.setWcs(wcs) record2.setD(self.weightKey, 1.0) record2.setBBox( lsst.geom.Box2I(lsst.geom.Point2I(60, 0), lsst.geom.Point2I(140, 100))) coaddPsf = measAlg.CoaddPsf(self.mycatalog, wcs) naiveAvgPos = lsst.geom.Point2D(50, 50) with self.assertRaises(pexExceptions.InvalidParameterError): coaddPsf.computeKernelImage(naiveAvgPos) # important test is that this doesn't throw: coaddPsf.computeKernelImage(coaddPsf.getAveragePosition())
def testValidPolygonPsf(self): """Demonstrate that we can use the validPolygon on Exposures in the CoaddPsf.""" # Create 9 separate records, each with its own peculiar Psf, Wcs, # weight, bounding box, and valid region. for i in range(1, 10): record = self.mycatalog.getTable().makeRecord() record.setPsf(measAlg.DoubleGaussianPsf(100, 100, i, 1.00, 0.0)) crpix = lsst.geom.PointD(1000 - 10.0 * i, 1000.0 - 10.0 * i) wcs = afwGeom.makeSkyWcs(crpix=crpix, crval=self.crval, cdMatrix=self.cdMatrix) record.setWcs(wcs) record['weight'] = 1.0 * (i + 1) record['id'] = i record.setBBox( lsst.geom.Box2I(lsst.geom.Point2I(0, 0), lsst.geom.Extent2I(1000, 1000))) validPolygon = afwGeom.Polygon( lsst.geom.Box2D(lsst.geom.Point2D(0, 0), lsst.geom.Extent2D(i * 100, i * 100))) record.setValidPolygon(validPolygon) self.mycatalog.append(record) # Create the CoaddPsf and check at three different points to ensure that the validPolygon is working mypsf = measAlg.CoaddPsf(self.mycatalog, self.wcsref, 'weight') for position in [ lsst.geom.Point2D(50, 50), lsst.geom.Point2D(500, 500), lsst.geom.Point2D(850, 850) ]: m1coadd, m2coadd = getCoaddSecondMoments(mypsf, position, True) m1, m2 = getPsfSecondMoments(mypsf, position) self.assertAlmostEqual(m1, m1coadd, delta=0.01) self.assertAlmostEqual(m2, m2coadd, delta=0.01)
def testBoostPersistence(self): psf1 = algorithms.DoubleGaussianPsf(self.ksize, self.ksize, self.sigma1, self.sigma2, self.b) psf2 = roundTripPsf(1, psf1) psf3 = roundTripPsf(1, psf1) self.comparePsfs(psf1, psf2) self.comparePsfs(psf1, psf3)
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 testBBox(self): """Check that computeBBox returns same BBox as realized Kernel Image and resized raises a Not Implemented Error""" sigma0 = 5 size = [50, 60, 70, 80] for i in range(4): record = self.mycatalog.getTable().makeRecord() psf = measAlg.DoubleGaussianPsf(size[i], size[i], sigma0, 1.00, 0.0) record.setPsf(psf) wcs = afwGeom.makeSkyWcs(crpix=self.crpix, crval=self.crval, cdMatrix=self.cdMatrix) record.setWcs(wcs) record['weight'] = 1.0 * (i + 1) record['id'] = i bbox = lsst.geom.Box2I(lsst.geom.Point2I(0, 0), lsst.geom.Extent2I(2000, 2000)) record.setBBox(bbox) self.mycatalog.append(record) mypsf = measAlg.CoaddPsf(self.mycatalog, self.wcsref, 'weight') self.assertEqual(mypsf.computeKernelImage().getBBox(), mypsf.computeBBox()) with self.assertRaises(pexExceptions.LogicError): mypsf.resized(100, 100)
def testValidPolygonPsf(self): """Test that we can use the validPolygon on exposures in the coadd psf""" print "ValidPolygonTest" # this is the coadd Wcs we want cd11 = 5.55555555e-05 cd12 = 0.0 cd21 = 0.0 cd22 = 5.55555555e-05 crval1 = 0.0 crval2 = 0.0 crpix = afwGeom.PointD(1000, 1000) crval = afwCoord.Coord(afwGeom.Point2D(crval1, crval2)) wcsref = afwImage.makeWcs(crval, crpix, cd11, cd12, cd21, cd22) schema = afwTable.ExposureTable.makeMinimalSchema() schema.addField("weight", type="D", doc="Coadd weight") mycatalog = afwTable.ExposureCatalog(schema) # Each of the 9 has its peculiar Psf, Wcs, weight, bounding box, and valid region. for i in range(1, 10, 1): record = mycatalog.getTable().makeRecord() psf = measAlg.DoubleGaussianPsf(100, 100, i, 1.00, 0.0) record.setPsf(psf) crpix = afwGeom.PointD(1000 - 10.0 * i, 1000.0 - 10.0 * i) wcs = afwImage.makeWcs(crval, crpix, cd11, cd12, cd21, cd22) record.setWcs(wcs) record['weight'] = 1.0 * (i + 1) record['id'] = i bbox = afwGeom.Box2I(afwGeom.Point2I(0, 0), afwGeom.Extent2I(1000, 1000)) record.setBBox(bbox) validPolygon_bbox = afwGeom.Box2D( afwGeom.Point2D(0, 0), afwGeom.Extent2D(i * 100, i * 100)) validPolygon = Polygon(validPolygon_bbox) record.setValidPolygon(validPolygon) mycatalog.append(record) # Create the coaddpsf and check at three different points to ensure that the validPolygon is working mypsf = measAlg.CoaddPsf(mycatalog, wcsref, 'weight') m1coadd, m2coadd = getCoaddSecondMoments(mypsf, afwGeom.Point2D(50, 50), True) m1, m2 = getPsfSecondMoments(mypsf, afwGeom.Point2D(50, 50)) self.assertTrue(testRelDiff(m1, m1coadd, .01)) self.assertTrue(testRelDiff(m2, m2coadd, .01)) m1coadd, m2coadd = getCoaddSecondMoments(mypsf, afwGeom.Point2D(500, 500), True) m1, m2 = getPsfSecondMoments(mypsf, afwGeom.Point2D(500, 500)) self.assertTrue(testRelDiff(m1, m1coadd, .01)) self.assertTrue(testRelDiff(m2, m2coadd, .01)) m1coadd, m2coadd = getCoaddSecondMoments(mypsf, afwGeom.Point2D(850, 850), True) m1, m2 = getPsfSecondMoments(mypsf, afwGeom.Point2D(850, 850)) self.assertTrue(testRelDiff(m1, m1coadd, .01)) self.assertTrue(testRelDiff(m2, m2coadd, .01))
def createDipole(w, h, xc, yc, scaling=100.0, fracOffset=1.2): # Make random noise image: set image plane to normal distribution image = afwImage.MaskedImageF(w, h) image.set(0) array = image.getImage().getArray() array[:, :] = np.random.randn(w, h) # Set variance to 1.0 var = image.getVariance() var.set(1.0) if display: ds9.mtv(image, frame=1, title="Original image") ds9.mtv(image.getVariance(), frame=2, title="Original variance") # Create Psf for dipole creation and measurement psfSize = 17 psf = measAlg.DoubleGaussianPsf(psfSize, psfSize, 2.0, 3.5, 0.1) psfFwhmPix = sigma2fwhm * psf.computeShape().getDeterminantRadius() psfim = psf.computeImage().convertF() psfim *= scaling / psf.computePeak() psfw, psfh = psfim.getDimensions() psfSum = np.sum(psfim.getArray()) # Create the dipole, offset by fracOffset of the Psf FWHM (pixels) offset = fracOffset * psfFwhmPix // 2 array = image.getImage().getArray() xp, yp = xc - psfw // 2 + offset, yc - psfh // 2 + offset array[yp:yp + psfh, xp:xp + psfw] += psfim.getArray() xn, yn = xc - psfw // 2 - offset, yc - psfh // 2 - offset array[yn:yn + psfh, xn:xn + psfw] -= psfim.getArray() if display: ds9.mtv(image, frame=3, title="With dipole") # Create an exposure, detect positive and negative peaks separately exp = afwImage.makeExposure(image) exp.setPsf(psf) config = measAlg.SourceDetectionConfig() config.thresholdPolarity = "both" config.reEstimateBackground = False schema = afwTable.SourceTable.makeMinimalSchema() task = measAlg.SourceDetectionTask(schema, config=config) table = afwTable.SourceTable.make(schema) results = task.makeSourceCatalog(table, exp) if display: ds9.mtv(image, frame=4, title="Detection plane") # Merge them together assert (len(results.sources) == 2) fpSet = results.fpSets.positive fpSet.merge(results.fpSets.negative, 0, 0, False) sources = afwTable.SourceCatalog(table) fpSet.makeSources(sources) assert (len(sources) == 1) s = sources[0] assert (len(s.getFootprint().getPeaks()) == 2) return psf, psfSum, exp, s
def testCreate(self): """Check that we can create a CoaddPsf with 9 elements""" print "CreatePsfTest" # this is the coadd Wcs we want cd11 = 5.55555555e-05 cd12 = 0.0 cd21 = 0.0 cd22 = 5.55555555e-05 crval1 = 0.0 crval2 = 0.0 crpix = afwGeom.PointD(1000, 1000) crval = afwCoord.Coord(afwGeom.Point2D(crval1, crval2)) wcsref = afwImage.makeWcs(crval, crpix, cd11, cd12, cd21, cd22) #also test that the weight field name is correctly observed schema = afwTable.ExposureTable.makeMinimalSchema() schema.addField("customweightname", type="D", doc="Coadd weight") mycatalog = afwTable.ExposureCatalog(schema) # Each of the 9 has its peculiar Psf, Wcs, weight, and bounding box. for i in range(1, 10, 1): record = mycatalog.getTable().makeRecord() psf = measAlg.DoubleGaussianPsf(100, 100, i, 1.00, 0.0) record.setPsf(psf) crpix = afwGeom.PointD(i * 1000.0, i * 1000.0) wcs = afwImage.makeWcs(crval, crpix, cd11, cd12, cd21, cd22) record.setWcs(wcs) record['customweightname'] = 1.0 * (i + 1) record['id'] = i bbox = afwGeom.Box2I(afwGeom.Point2I(0, 0), afwGeom.Extent2I(i * 1000, i * 1000)) record.setBBox(bbox) mycatalog.append(record) #create the coaddpsf mypsf = measAlg.CoaddPsf(mycatalog, wcsref, 'customweightname') # check to be sure that we got the right number of components, in the right order self.assertTrue(mypsf.getComponentCount() == 9) for i in range(1, 10, 1): wcs = mypsf.getWcs(i - 1) psf = mypsf.getPsf(i - 1) bbox = mypsf.getBBox(i - 1) weight = mypsf.getWeight(i - 1) id = mypsf.getId(i - 1) self.assertTrue(i == id) self.assertTrue(weight == 1.0 * (i + 1)) self.assertTrue(bbox.getBeginX() == 0) self.assertTrue(bbox.getBeginY() == 0) self.assertTrue(bbox.getEndX() == 1000 * i) self.assertTrue(bbox.getEndY() == 1000 * i) self.assertTrue(wcs.getPixelOrigin().getX() == (1000.0 * i)) self.assertTrue(wcs.getPixelOrigin().getY() == (1000.0 * i)) m0, xbar, ybar, mxx, myy, x0, y0 = getPsfMoments( psf, afwGeom.Point2D(0, 0)) self.assertTrue(testRelDiff(i * i, mxx, .01)) self.assertTrue(testRelDiff(i * i, myy, .01))
def testDefaultSize(self): """Test of both default size and specified size""" print "DefaultSizeTest" sigma0 = 5 # set the peak of the outer guassian to 0 so this is really a single gaussian. psf = measAlg.DoubleGaussianPsf(60, 60, 1.5 * sigma0, 1, 0.0) if False and display: im = psf.computeImage(afwGeom.PointD(xwid / 2, ywid / 2)) ds9.mtv(im, title="N(%g) psf" % sigma0, frame=0) # this is the coadd Wcs we want cd11 = 5.55555555e-05 cd12 = 0.0 cd21 = 0.0 cd22 = 5.55555555e-05 crval1 = 0.0 crval2 = 0.0 crpix = afwGeom.PointD(1000, 1000) crval = afwCoord.Coord(afwGeom.Point2D(crval1, crval2)) wcsref = afwImage.makeWcs(crval, crpix, cd11, cd12, cd21, cd22) # Now make the catalog schema = afwTable.ExposureTable.makeMinimalSchema() schema.addField("weight", type="D", doc="Coadd weight") mycatalog = afwTable.ExposureCatalog(schema) record = mycatalog.getTable().makeRecord() psf = measAlg.DoubleGaussianPsf(100, 100, 10.0, 1.00, 1.0) record.setPsf(psf) wcs = afwImage.makeWcs(crval, crpix, cd11, cd12, cd21, cd22) record.setWcs(wcs) record['weight'] = 1.0 record['id'] = 1 bbox = afwGeom.Box2I(afwGeom.Point2I(0, 0), afwGeom.Extent2I(2000, 2000)) record.setBBox(bbox) mycatalog.append(record) mypsf = measAlg.CoaddPsf(mycatalog, wcsref) #, 'weight') m1coadd, m2coadd = getCoaddSecondMoments(mypsf, afwGeom.Point2D(0, 0)) m1, m2 = getPsfSecondMoments(mypsf, afwGeom.Point2D(1000, 1000)) self.assertTrue(testRelDiff(m1, m1coadd, .01)) self.assertTrue(testRelDiff(m2, m2coadd, .01))
def testFailures(self): """Test deblender failure flagging (#2871) We create a good source which is expected to pass and a bad source which is expected to fail because its footprint goes off the image. This latter case may not happen in practise, but it is useful for checking the plumbing of the deblender. """ import lsst.meas.deblender as measDeb self.checkDeblender() xGood, yGood = 57, 86 # Required to be in image so we can evaluate the PSF; will put neighbour just outside xBad, yBad = 0, 0 flux = 100.0 dims = geom.Extent2I(128, 128) mi = afwImage.MaskedImageF(dims) mi.getVariance().set(1.0) image = mi.getImage() image.set(0) image[xGood, yGood, afwImage.LOCAL] = flux exposure = afwImage.makeExposure(mi) psf = algorithms.DoubleGaussianPsf(21, 21, 3.) exposure.setPsf(psf) schema = afwTable.SourceTable.makeMinimalSchema() config = measDeb.SourceDeblendConfig() config.catchFailures = True task = measDeb.SourceDeblendTask(schema, config=config) catalog = afwTable.SourceCatalog(schema) def makeSource(x, y, offset=-2, size=3.0): """Make a source in the catalog Two peaks are created: one at the specified position, and one offset in x,y. The footprint is of the nominated size. """ src = catalog.addNew() spans = afwGeom.SpanSet.fromShape(int(size), offset=(x, y)) foot = afwDetection.Footprint(spans) foot.addPeak(x, y, flux) foot.addPeak(x + offset, y + offset, flux) src.setFootprint(foot) return src good = makeSource(xGood, yGood) bad = makeSource(xBad, yBad) task.run(exposure, catalog) self.assertFalse(good.get('deblend_failed')) self.assertTrue(bad.get('deblend_failed'))
def createPsf(fwhm): """Make a double Gaussian PSF @param[in] fwhm FWHM of double Gaussian smoothing kernel @return measAlg.DoubleGaussianPsf """ ksize = 4 * int(fwhm) + 1 return measAlg.DoubleGaussianPsf(ksize, ksize, fwhm / (2 * math.sqrt(2 * math.log(2))))
def testTooBig(self): self.subconfig.kernelSize = self.ksize psf = measAlg.DoubleGaussianPsf(self.ksize, self.ksize, self.sigma2) psfMatch = ipDiffim.ModelPsfMatchTask(config=self.config) try: psfMatch.run(self.exp, psf) except Exception: pass else: self.fail()
def testPropagateVisitInfo(self): """Test that a PSF-matched exposure preserves the original VisitInfo. """ self.exp.getInfo().setVisitInfo(makeVisitInfo()) psfModel = measAlg.DoubleGaussianPsf(self.ksize + 2, self.ksize + 2, self.sigma2) psfMatch = ipDiffim.ModelPsfMatchTask(config=self.config) psfMatchedExposure = psfMatch.run(self.exp, psfModel).psfMatchedExposure self.assertEqual(psfMatchedExposure.getInfo().getVisitInfo(), self.exp.getInfo().getVisitInfo())
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 setUp(self): self.FWHM = 5 self.psf = algorithms.DoubleGaussianPsf(15, 15, self.FWHM/(2*sqrt(2*log(2)))) maskedImageFile = os.path.join(eups.productDir("afwdata"), "CFHT", "D4", "cal-53535-i-797722_1.fits") self.mi = afwImage.MaskedImageF(maskedImageFile) if False: # use sub-image? self.mi = self.mi.Factory(self.mi, afwImage.BBox(afwImage.PointI(760, 20), 256, 256)) self.mi.getMask().addMaskPlane("INTERP") self.badPixels = defects.policyToBadRegionList(os.path.join(eups.productDir("meas_algorithms"), "policy", "BadPixels.paf"))