def testCatFluxErr(self): """Test catalog flux errors. Notes ----- This test will break if ``UseNaiveFluxErr = False``~ The alternate method significantly overestimates noise, causing this test to fail. It is likely that this test will need to be modified if the noise calculation is updated. """ # Pick arbitrary but unique values for the test case source_test_instFlux = 5.5 source_test_sigma = 0.23 source_test_centroid = lsst.geom.Point2D(5, 7.3) sourceCat = initializeSourceCatalog(schema=self.schema, name=self.name, instFlux=source_test_instFlux, sigma=source_test_sigma, centroid=source_test_centroid) instFluxName = self.name + "_instFlux" instFluxErrName = self.name + "_instFluxErr" instFluxErrKey = self.schema.find(instFluxErrName).key apCorrMap = afwImage.ApCorrMap() bbox = lsst.geom.Box2I(lsst.geom.Point2I(0, 0), lsst.geom.ExtentI(10, 10)) coefficients = np.ones((1, 1), dtype=np.float64) coefficients_sigma = np.ones((1, 1), dtype=np.float64) apCorrMap[instFluxName] = ChebyshevBoundedField(bbox, coefficients) apCorrMap[instFluxErrName] = ChebyshevBoundedField(bbox, coefficients_sigma) self.ap_corr_task.run(sourceCat, apCorrMap) self.assertAlmostEqual(sourceCat[instFluxErrKey], source_test_sigma)
def setUp(self): super().setUp() afwImage.Filter.reset() afwImage.FilterProperty.reset() defineFilter("g", 470.0) self.wcs = afwGeom.makeSkyWcs( lsst.geom.Point2D(0.0, 0.0), lsst.geom.SpherePoint(2.0, 34.0, lsst.geom.degrees), np.identity(2), ) self.photoCalib = afwImage.PhotoCalib(1.5) self.psf = DummyPsf(2.0) self.detector = DetectorWrapper().detector self.summaryStats = afwImage.ExposureSummaryStats(ra=100.0) self.polygon = afwGeom.Polygon( lsst.geom.Box2D(lsst.geom.Point2D(0.0, 0.0), lsst.geom.Point2D(25.0, 20.0))) self.coaddInputs = afwImage.CoaddInputs() self.apCorrMap = afwImage.ApCorrMap() self.transmissionCurve = afwImage.TransmissionCurve.makeIdentity() self.exposureInfo = afwImage.ExposureInfo() gFilter = afwImage.Filter("g") gFilterLabel = afwImage.FilterLabel(band="g") self.exposureInfo.setFilter(gFilter) self.exposureInfo.setFilterLabel(gFilterLabel)
def testFailureFlagged(self): # Check that aperture correction flag is set to True if aperture correction is invalid (negative) flagName = self.name + "_flag_apCorr" flagKey = self.schema.find(flagName).key source_test_flux = 5.2 source_test_centroid = afwGeom.Point2D(5, 7.1) sourceCat = initializeSourceCatalog(schema=self.schema, name=self.name, flux=source_test_flux, sigma=0, centroid=source_test_centroid) fluxName = self.name + "_flux" fluxSigmaName = self.name + "_fluxSigma" apCorrMap = afwImage.ApCorrMap() bbox = afwGeom.Box2I(afwGeom.Point2I(0, 0), afwGeom.ExtentI(10, 10)) coefficients = -(numpy.ones((1, 1), dtype=float)) coefficients_sigma = numpy.zeros((1, 1), dtype=float) apCorrMap[fluxName] = ChebyshevBoundedField(bbox, coefficients) apCorrMap[fluxSigmaName] = ChebyshevBoundedField(bbox, coefficients_sigma) self.ap_corr_task.run(sourceCat, apCorrMap) self.assertTrue(sourceCat[flagKey])
def testCatFluxUnchanged(self): # Pick arbitrary but unique values for the test case source_test_flux = 5.3 source_test_centroid = afwGeom.Point2D(5, 7.1) sourceCat = initializeSourceCatalog(schema=self.schema, name=self.name, flux=source_test_flux, sigma=0, centroid=source_test_centroid) fluxName = self.name + "_flux" fluxSigmaName = self.name + "_fluxSigma" fluxKey = self.schema.find(fluxName).key apCorrMap = afwImage.ApCorrMap() bbox = afwGeom.Box2I(afwGeom.Point2I(0, 0), afwGeom.ExtentI(10, 10)) coefficients = numpy.ones((1, 1), dtype=float) coefficients_sigma = numpy.zeros((1, 1), dtype=float) apCorrMap[fluxName] = ChebyshevBoundedField(bbox, coefficients) apCorrMap[fluxSigmaName] = ChebyshevBoundedField(bbox, coefficients_sigma) self.ap_corr_task.run(sourceCat, apCorrMap) self.assertEqual(sourceCat[fluxKey], source_test_flux)
def testCatFluxUnchanged(self): # Pick arbitrary but unique values for the test case source_test_instFlux = 5.3 source_test_centroid = lsst.geom.Point2D(5, 7.1) sourceCat = initializeSourceCatalog(schema=self.schema, name=self.name, instFlux=source_test_instFlux, sigma=0, centroid=source_test_centroid) instFluxName = self.name + "_instFlux" instFluxErrName = self.name + "_instFluxErr" instFluxKey = self.schema.find(instFluxName).key apCorrMap = afwImage.ApCorrMap() bbox = lsst.geom.Box2I(lsst.geom.Point2I(0, 0), lsst.geom.ExtentI(10, 10)) coefficients = np.ones((1, 1), dtype=np.float64) coefficients_sigma = np.zeros((1, 1), dtype=np.float64) apCorrMap[instFluxName] = ChebyshevBoundedField(bbox, coefficients) apCorrMap[instFluxErrName] = ChebyshevBoundedField(bbox, coefficients_sigma) self.ap_corr_task.run(sourceCat, apCorrMap) self.assertEqual(sourceCat[instFluxKey], source_test_instFlux)
def testSuccessUnflagged(self): # Check that the aperture correction flag is set to False if aperture # correction was successfully run flagName = self.name + "_flag_apCorr" flagKey = self.schema.find(flagName).key source_test_instFlux = 5.1 source_test_centroid = lsst.geom.Point2D(5, 7.1) sourceCat = initializeSourceCatalog(schema=self.schema, name=self.name, instFlux=source_test_instFlux, sigma=0, centroid=source_test_centroid) instFluxName = self.name + "_instFlux" instFluxErrName = self.name + "_instFluxErr" apCorrMap = afwImage.ApCorrMap() bbox = lsst.geom.Box2I(lsst.geom.Point2I(0, 0), lsst.geom.ExtentI(10, 10)) coefficients = np.ones((1, 1), dtype=np.float64) coefficients_sigma = np.zeros((1, 1), dtype=np.float64) apCorrMap[instFluxName] = ChebyshevBoundedField(bbox, coefficients) apCorrMap[instFluxErrName] = ChebyshevBoundedField(bbox, coefficients_sigma) self.ap_corr_task.run(sourceCat, apCorrMap) self.assertFalse(sourceCat[flagKey])
def testCoaddApCorrMap(self): """Check that we can create and use a coadd ApCorrMap.""" coaddBox = afwGeom.Box2I(afwGeom.Point2I(0, 0), afwGeom.Extent2I(100, 100)) scale = 5.0e-5*afwGeom.degrees cdMatrix = afwGeom.makeCdMatrix(scale=scale) crval = afwGeom.SpherePoint(0.0, 0.0, afwGeom.degrees) center = afwGeom.Point2D(afwGeom.Extent2D(coaddBox.getDimensions())*0.5) coaddWcs = afwGeom.makeSkyWcs(crpix=afwGeom.Point2D(0, 0), crval=crval, cdMatrix=cdMatrix) schema = afwTable.ExposureTable.makeMinimalSchema() weightKey = schema.addField("customweightname", type="D", doc="Coadd weight") catalog = afwTable.ExposureCatalog(schema) # Non-overlapping num = 5 inputBox = afwGeom.Box2I(afwGeom.Point2I(0, 0), afwGeom.Extent2I(10, 10)) validBox = afwGeom.Box2I(afwGeom.Point2I(0, 0), afwGeom.Extent2I(7, 7)) pointList = [] pointListValid = [] for i in range(num): value = np.array([[1]], dtype=float) # Constant with value = i+1 apCorrMap = afwImage.ApCorrMap() bf = afwMath.ChebyshevBoundedField(inputBox, value*(i + 1)) apCorrMap.set("only", bf) point = afwGeom.Point2D(0, 0) - afwGeom.Extent2D(coaddBox.getDimensions())*(i+0.5)/num wcs = afwGeom.makeSkyWcs(crpix=point, crval=crval, cdMatrix=cdMatrix) center = afwGeom.Box2D(inputBox).getCenter() pointList.append(coaddWcs.skyToPixel(wcs.pixelToSky(center))) # This point will only be valid for the second overlapping record pointValid = center + afwGeom.Extent2D(4, 4) pointListValid.append(coaddWcs.skyToPixel(wcs.pixelToSky(pointValid))) # A record with the valid polygon defining a limited region record = catalog.getTable().makeRecord() record.setWcs(wcs) record.setBBox(inputBox) record.setApCorrMap(apCorrMap) record.set(weightKey, i + 1) record['id'] = i record.setValidPolygon(afwGeom.Polygon(afwGeom.Box2D(validBox))) catalog.append(record) # An overlapping record with the whole region as valid record = catalog.getTable().makeRecord() record.setWcs(wcs) record.setBBox(inputBox) apCorrMap = afwImage.ApCorrMap() bf = afwMath.ChebyshevBoundedField(inputBox, value*(i + 2)) apCorrMap.set("only", bf) record.setApCorrMap(apCorrMap) record.set(weightKey, i + 2) record['id'] = i + num record.setValidPolygon(afwGeom.Polygon(afwGeom.Box2D(inputBox))) catalog.append(record) apCorrMap = measAlg.makeCoaddApCorrMap(catalog, coaddBox, coaddWcs, "customweightname") # This will test a point where both records contribute self.assertApCorrMap(apCorrMap, pointList) # Only the second record will be valid for this point self.assertApCorrMapValid(apCorrMap, pointListValid) filename = os.path.join(os.path.dirname(os.path.realpath(__file__)), "coaddApCorrMap.fits") exposure = afwImage.ExposureF(1, 1) exposure.getInfo().setApCorrMap(apCorrMap) exposure.writeFits(filename) exposure = afwImage.ExposureF(filename) self.assertApCorrMap(exposure.getInfo().getApCorrMap(), pointList) self.assertApCorrMapValid(exposure.getInfo().getApCorrMap(), pointListValid) os.unlink(filename)
def testUndeblendedMeasurement(self): """Check undeblended measurement and aperture correction""" width, height = 100, 100 # Dimensions of image x0, y0 = 1234, 5678 # Offset of image radius = 3.0 # Aperture radius xCenter, yCenter = width//2, height//2 # Position of first source; integer values, for convenience xOffset, yOffset = 1, 1 # Offset from first source to second source flux1, flux2 = 1000, 1 # Flux of sources apCorrValue = 3.21 # Aperture correction value to apply image = afwImage.MaskedImageF(afwGeom.ExtentI(width, height)) image.setXY0(x0, y0) image.getVariance().set(1.0) schema = afwTable.SourceTable.makeMinimalSchema() schema.addField("centroid_x", type=np.float64) schema.addField("centroid_y", type=np.float64) schema.addField("centroid_flag", type='Flag') schema.getAliasMap().set("slot_Centroid", "centroid") sfmConfig = measBase.SingleFrameMeasurementConfig() algName = "base_CircularApertureFlux" for subConfig in (sfmConfig.plugins, sfmConfig.undeblended): subConfig.names = [algName] subConfig[algName].radii = [radius] subConfig[algName].maxSincRadius = 0 # Disable sinc photometry because we're undersampled slots = sfmConfig.slots slots.centroid = "centroid" slots.shape = None slots.psfShape = None slots.apFlux = None slots.modelFlux = None slots.psfFlux = None slots.instFlux = None slots.calibFlux = None fieldName = lsst.meas.base.CircularApertureFluxAlgorithm.makeFieldPrefix(algName, radius) measBase.addApCorrName(fieldName) apCorrConfig = measBase.ApplyApCorrConfig() apCorrConfig.proxies = {"undeblended_" + fieldName: fieldName} sfm = measBase.SingleFrameMeasurementTask(config=sfmConfig, schema=schema) apCorr = measBase.ApplyApCorrTask(config=apCorrConfig, schema=schema) cat = afwTable.SourceCatalog(schema) parent = cat.addNew() parent.set("centroid_x", x0 + xCenter) parent.set("centroid_y", y0 + yCenter) spanSetParent = afwGeom.SpanSet.fromShape(int(radius)) spanSetParent = spanSetParent.shiftedBy(x0 + xCenter, y0 + yCenter) parent.setFootprint(afwDetection.Footprint(spanSetParent)) # First child is bright, dominating the blend child1 = cat.addNew() child1.set("centroid_x", parent.get("centroid_x")) child1.set("centroid_y", parent.get("centroid_y")) child1.setParent(parent.getId()) image.set(xCenter, yCenter, (flux1, 0, 0)) spanSetChild1 = afwGeom.SpanSet.fromShape(1) spanSetChild1 = spanSetChild1.shiftedBy(x0 + xCenter, y0 + yCenter) foot1 = afwDetection.Footprint(spanSetChild1) child1.setFootprint(afwDetection.HeavyFootprintF(foot1, image)) # Second child is fainter, but we want to be able to measure it! child2 = cat.addNew() child2.set("centroid_x", parent.get("centroid_x") + xOffset) child2.set("centroid_y", parent.get("centroid_y") + yOffset) child2.setParent(parent.getId()) image.set(xCenter + xOffset, yCenter + yOffset, (flux2, 0, 0)) spanSetChild2 = afwGeom.SpanSet.fromShape(1) tmpPoint = (x0 + xCenter + xOffset, y0 + yCenter + yOffset) spanSetChild2 = spanSetChild2.shiftedBy(*tmpPoint) foot2 = afwDetection.Footprint(spanSetChild2) child2.setFootprint(afwDetection.HeavyFootprintF(foot2, image)) spans = foot1.spans.union(foot2.spans) bbox = afwGeom.Box2I() bbox.include(foot1.getBBox()) bbox.include(foot2.getBBox()) parent.setFootprint(afwDetection.Footprint(spans, bbox)) exposure = afwImage.makeExposure(image) sfm.run(cat, exposure) def checkSource(source, baseName, expectedFlux): """Check that we get the expected results""" self.assertEqual(source.get(baseName + "_flux"), expectedFlux) self.assertGreater(source.get(baseName + "_fluxSigma"), 0) self.assertFalse(source.get(baseName + "_flag")) # Deblended checkSource(child1, fieldName, flux1) checkSource(child2, fieldName, flux2) # Undeblended checkSource(child1, "undeblended_" + fieldName, flux1 + flux2) checkSource(child2, "undeblended_" + fieldName, flux1 + flux2) # Apply aperture correction apCorrMap = afwImage.ApCorrMap() apCorrMap[fieldName + "_flux"] = afwMath.ChebyshevBoundedField( image.getBBox(), apCorrValue*np.ones((1, 1), dtype=np.float64) ) apCorrMap[fieldName + "_fluxSigma"] = afwMath.ChebyshevBoundedField( image.getBBox(), apCorrValue*np.zeros((1, 1), dtype=np.float64) ) apCorr.run(cat, apCorrMap) # Deblended checkSource(child1, fieldName, flux1*apCorrValue) checkSource(child2, fieldName, flux2*apCorrValue) # Undeblended checkSource(child1, "undeblended_" + fieldName, (flux1 + flux2)*apCorrValue) checkSource(child2, "undeblended_" + fieldName, (flux1 + flux2)*apCorrValue) self.assertIn(fieldName + "_apCorr", schema) self.assertIn(fieldName + "_apCorrSigma", schema) self.assertIn("undeblended_" + fieldName + "_apCorr", schema) self.assertIn("undeblended_" + fieldName + "_apCorrSigma", schema)