def assembleMetadata(self, coaddExposure, tempExpRefList, weightList): """Set the metadata for the coadd This basic implementation simply sets the filter from the first input. @param coaddExposure: The target image for the coadd @param tempExpRefList: List of data references to tempExp @param weightList: List of weights """ tempExpName = self.getTempExpDatasetName() # We load a single pixel of each coaddTempExp, because we just want to get at the metadata # (and we need more than just the PropertySet that contains the header). See #2777. bbox = afwGeom.Box2I(afwGeom.Point2I(0,0), afwGeom.Extent2I(1,1)) first = True coaddInputs = coaddExposure.getInfo().getCoaddInputs() for tempExpRef, weight in zip(tempExpRefList, weightList): tempExp = tempExpRef.get(tempExpName + "_sub", bbox=bbox, imageOrigin="LOCAL", immediate=True) if first: coaddExposure.setFilter(tempExp.getFilter()) first = False self.inputRecorder.addVisitToCoadd(coaddInputs, tempExp, weight) coaddInputs.visits.sort() if self.config.doPsfMatch: psf = self.config.modelPsf.apply() else: psf = measAlg.CoaddPsf(coaddInputs.ccds, coaddExposure.getWcs()) coaddExposure.setPsf(psf) apCorrMap = measAlg.makeCoaddApCorrMap(coaddInputs.ccds, coaddExposure.getBBox(afwImage.PARENT), coaddExposure.getWcs()) coaddExposure.getInfo().setApCorrMap(apCorrMap)
def finish(self, coaddTempExp, nGoodPix=None): """Finish creating the CoaddInputs for a CoaddTempExp. @param[in,out] coaddTempExp Exposure object from which to obtain the PSF, WCS, and bounding box for the entry in the 'visits' table. On return, the completed CoaddInputs object will be attached to it. @param[in] nGoodPix Total number of good pixels in the CoaddTempExp; ignored unless saveVisitGoodPix is true. """ self._setExposureInfoInRecord(exposure=coaddTempExp, record=self.visitRecord) if self.task.config.saveVisitGoodPix: self.visitRecord.setI(self.task.visitGoodPixKey, nGoodPix) coaddTempExp.getInfo().setCoaddInputs(self.coaddInputs) wcs = coaddTempExp.getWcs() if False: # This causes a test failure, pending fix in issue HSC-802 coaddTempExp.setPsf(CoaddPsf(self.coaddInputs.ccds, wcs)) apCorrMap = makeCoaddApCorrMap(self.coaddInputs.ccds, coaddTempExp.getBBox(afwImage.PARENT), wcs) coaddTempExp.getInfo().setApCorrMap(apCorrMap)
def testCoaddApCorrMap(self): """Check that we can create and use a coadd ApCorrMap.""" coaddBox = lsst.geom.Box2I(lsst.geom.Point2I(0, 0), lsst.geom.Extent2I(100, 100)) scale = 5.0e-5*lsst.geom.degrees cdMatrix = afwGeom.makeCdMatrix(scale=scale) crval = lsst.geom.SpherePoint(0.0, 0.0, lsst.geom.degrees) center = lsst.geom.Point2D(lsst.geom.Extent2D(coaddBox.getDimensions())*0.5) coaddWcs = afwGeom.makeSkyWcs(crpix=lsst.geom.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 = lsst.geom.Box2I(lsst.geom.Point2I(0, 0), lsst.geom.Extent2I(10, 10)) validBox = lsst.geom.Box2I(lsst.geom.Point2I(0, 0), lsst.geom.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 = lsst.geom.Point2D(0, 0) - lsst.geom.Extent2D(coaddBox.getDimensions())*(i+0.5)/num wcs = afwGeom.makeSkyWcs(crpix=point, crval=crval, cdMatrix=cdMatrix) center = lsst.geom.Box2D(inputBox).getCenter() pointList.append(coaddWcs.skyToPixel(wcs.pixelToSky(center))) # This point will only be valid for the second overlapping record pointValid = center + lsst.geom.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(lsst.geom.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(lsst.geom.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 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)