def testSmallSrc(self): """Verify that a source image that is too small will not raise an exception This tests another bug that was fixed in ticket #2441 """ fromWcs = afwGeom.makeSkyWcs( crpix=lsst.geom.Point2D(0, 0), crval=lsst.geom.SpherePoint(359, 0, lsst.geom.degrees), cdMatrix=afwGeom.makeCdMatrix(scale=1.0e-8*lsst.geom.degrees), ) fromExp = afwImage.ExposureF(afwImage.MaskedImageF(1, 1), fromWcs) toWcs = afwGeom.makeSkyWcs( crpix=lsst.geom.Point2D(0, 0), crval=lsst.geom.SpherePoint(358, 0, lsst.geom.degrees), cdMatrix=afwGeom.makeCdMatrix(scale=1.1e-8*lsst.geom.degrees), ) toExp = afwImage.ExposureF(afwImage.MaskedImageF(10, 10), toWcs) warpControl = afwMath.WarpingControl("lanczos3") # if a bug described in ticket #2441 is present, this will raise an # exception: numGoodPix = afwMath.warpExposure(toExp, fromExp, warpControl) self.assertEqual(numGoodPix, 0) imArr, maskArr, varArr = toExp.getMaskedImage().getArrays() self.assertTrue(np.all(np.isnan(imArr))) self.assertTrue(np.all(np.isinf(varArr))) noDataBitMask = afwImage.Mask.getPlaneBitMask("NO_DATA") self.assertTrue(np.all(maskArr == noDataBitMask))
def setUp(self): # Construct an arbitrary WCS for testing. crval = lsst.geom.SpherePoint(45.0, 45.0, lsst.geom.degrees) scale = 0.2*lsst.geom.arcseconds crpix = lsst.geom.PointD(100, 100) self.wcs = afwGeom.makeSkyWcs(crpix=crpix, crval=crval, cdMatrix=afwGeom.makeCdMatrix(scale=scale))
def testMakeSimpleWcsMetadata(self): crpix = Point2D(111.1, 222.2) crval = SpherePoint(45.6 * degrees, 12.3 * degrees) scale = 1 * arcseconds for orientation in (0 * degrees, 21 * degrees): cdMatrix = makeCdMatrix(scale=scale, orientation=orientation) for projection in ("TAN", "STG"): metadata = makeSimpleWcsMetadata(crpix=crpix, crval=crval, cdMatrix=cdMatrix, projection=projection) desiredLength = 12 if orientation == 0 * degrees else 14 self.assertEqual(len(metadata.names()), desiredLength) self.assertEqual(metadata.getScalar("RADESYS"), "ICRS") self.assertAlmostEqual(metadata.getScalar("EQUINOX"), 2000.0) self.assertEqual(metadata.getScalar("CTYPE1"), "RA---" + projection) self.assertEqual(metadata.getScalar("CTYPE2"), "DEC--" + projection) for i in range(2): self.assertAlmostEqual(metadata.getScalar("CRPIX%d" % (i + 1,)), crpix[i] + 1) self.assertAlmostEqual(metadata.getScalar("CRVAL%d" % (i + 1,)), crval[i].asDegrees()) self.assertEqual(metadata.getScalar("CUNIT%d" % (i + 1,)), "deg") for i in range(2): for j in range(2): name = "CD%d_%d" % (i + 1, j + 1) if cdMatrix[i, j] != 0: self.assertAlmostEqual(metadata.getScalar(name), cdMatrix[i, j]) else: self.assertFalse(metadata.exists(name))
def test(self): schema = afwTable.ExposureTable.makeMinimalSchema() schema.addField("ccd", np.int32, doc="CCD number") schema.addField("visit", np.int32, doc="Visit number") schema.addField("goodpix", np.int32, doc="Number of good pixels") schema.addField("weight", float, doc="Weighting for this CCD") ccds = afwTable.ExposureCatalog(schema) scale = 1.0e-4*lsst.geom.degrees wcs = afwGeom.makeSkyWcs(crpix=lsst.geom.Point2D(0.0, 0.0), crval=lsst.geom.SpherePoint(0.0, 0.0, lsst.geom.degrees), cdMatrix=afwGeom.makeCdMatrix(scale=scale)) new = ccds.addNew() new.set("id", 0) new.set("bbox_min_x", 0) new.set("bbox_min_y", 0) new.set("bbox_max_x", 1024) new.set("bbox_max_y", 1024) # The following lines are critical for reproducing the bug, because # the code is reading a double starting at the 'ccd' (offset 24), and # it sees a zero (from the zero in 'ccd' and the leading zeros in 'visit'). new.set("ccd", 0) new.set("visit", 6789) new.set("goodpix", 987654321) new.set("weight", 1.0) new.setPsf(measAlg.SingleGaussianPsf(23, 23, 2.345)) new.setWcs(wcs) # In the presence of the bug, the following fails with # lsst::pex::exceptions::RuntimeError thrown in src/CoaddPsf.cc # with message: "Could not find a valid average position for CoaddPsf" measAlg.CoaddPsf(ccds, wcs)
def setUp(self): # make a nominal match list where the distances are 0; test can then modify # source centroid, reference coord or distance field for each match, as desired self.wcs = afwGeom.makeSkyWcs(crpix=lsst.geom.Point2D(1500, 1500), crval=lsst.geom.SpherePoint(215.5, 53.0, lsst.geom.degrees), cdMatrix=afwGeom.makeCdMatrix(scale=5.1e-5*lsst.geom.degrees)) self.bboxD = lsst.geom.Box2D(lsst.geom.Point2D(10, 100), lsst.geom.Extent2D(1000, 1500)) self.numMatches = 25 sourceSchema = afwTable.SourceTable.makeMinimalSchema() # add centroid (and many other unwanted fields) to sourceSchema SingleFrameMeasurementTask(schema=sourceSchema) self.sourceCentroidKey = afwTable.Point2DKey(sourceSchema["slot_Centroid"]) self.sourceCat = afwTable.SourceCatalog(sourceSchema) refSchema = afwTable.SourceTable.makeMinimalSchema() self.refCoordKey = afwTable.CoordKey(refSchema["coord"]) self.refCat = afwTable.SourceCatalog(refSchema) self.matchList = [] np.random.seed(5) pixPointList = [lsst.geom.Point2D(pos) for pos in np.random.random_sample([self.numMatches, 2])*self.bboxD.getDimensions() + self.bboxD.getMin()] for pixPoint in pixPointList: src = self.sourceCat.addNew() src.set(self.sourceCentroidKey, pixPoint) ref = self.refCat.addNew() ref.set(self.refCoordKey, self.wcs.pixelToSky(pixPoint)) match = afwTable.ReferenceMatch(ref, src, 0) self.matchList.append(match)
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()
def _create_wcs(bbox, pixel_scale, ra, dec, sky_rotation): """Create a wcs (coordinate system). Parameters ---------- bbox : lsst.afw.geom.Box2I object A bounding box. pixel_scale : lsst.afw.geom.Angle Plate scale, as an Angle. ra : lsst.afw.geom.Angle Right Ascension of the reference pixel, as an `Angle`. dec : lsst.afw.geom.Angle Declination of the reference pixel, as an Angle. sky_rotation : lsst.afw.geom.Angle Rotation of the image axis, East from North. Returns ------- Returns a lsst.afw.image.wcs object. """ crval = afwGeom.SpherePoint(ra, dec) crpix = afwGeom.Box2D(bbox).getCenter() cd_matrix = makeCdMatrix(scale=pixel_scale, orientation=sky_rotation, flipX=True) wcs = makeSkyWcs(crpix=crpix, crval=crval, cdMatrix=cd_matrix) return(wcs)
def testRotatePsf(self): """Check that we can create a CoaddPsf with 10 elements.""" print("RotatePsfTest") cdMatrix = afwGeom.makeCdMatrix( scale=5.55555555e-05*lsst.geom.degrees, orientation=90*lsst.geom.degrees, flipX=True, ) wcs = afwGeom.makeSkyWcs(crpix=self.crpix, crval=self.crval, cdMatrix=cdMatrix) # make a single record with an oblong Psf record = self.mycatalog.getTable().makeRecord() psf = makeBiaxialGaussianPsf(100, 100, 1.0, 6.0, 0.0) record.setPsf(psf) 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) m0, xbar, ybar, mxx, myy, x0, y0 = getPsfMoments(psf, lsst.geom.Point2D(0.25, 0.75)) cm0, cxbar, cybar, cmxx, cmyy, cx0, cy0 = getPsfMoments(mypsf, lsst.geom.Point2D(0.25, 0.75)) self.assertAlmostEqual(mxx, cmyy, delta=0.01) self.assertAlmostEqual(myy, cmxx, delta=0.01)
def setUp(self): np.random.seed(12345) self.config = measAstrom.MatchPessimisticBTask.ConfigClass() # Value below is to assure all matches are selected. The # original test is set for a 3 arcsecond max match distance # using matchOptimisticB. self.config.minMatchDistPixels = 2.0 self.MatchPessimisticB = measAstrom.MatchPessimisticBTask( config=self.config) self.wcs = afwGeom.makeSkyWcs(crpix=lsst.geom.Point2D(791.4, 559.7), crval=lsst.geom.SpherePoint(36.930640, -4.939560, lsst.geom.degrees), cdMatrix=afwGeom.makeCdMatrix(scale=5.17e-5*lsst.geom.degrees)) self.distortedWcs = self.wcs self.filename = os.path.join(os.path.dirname(__file__), "cat.xy.fits") self.tolArcsec = .4 self.tolPixel = .1 # 3 of the objects are removed by the source selector and are used in # matching hence the 183 number vs the total of 186. This is also why # these three objects are missing in the testReferenceFilter test. self.expectedMatches = 183
def setUp(self): crval = lsst.geom.SpherePoint(44, 45, lsst.geom.degrees) crpix = lsst.geom.Point2D(15000, 4000) scale = 1 * lsst.geom.arcseconds cdMatrix = afwGeom.makeCdMatrix(scale=scale, flipX=True) self.tanWcs = afwGeom.makeSkyWcs(crpix=crpix, crval=crval, cdMatrix=cdMatrix) self.loadData()
def testTanWcsFromFrameDict(self): """Test making a TAN WCS from a FrameDict """ cdMatrix = makeCdMatrix(scale=self.scale) skyWcs = makeSkyWcs(crpix=self.crpix, crval=self.crvalList[0], cdMatrix=cdMatrix) self.checkFrameDictConstructor(skyWcs, bbox=self.bbox)
def setUp(self): crval = afwGeom.SpherePoint(44, 45, afwGeom.degrees) crpix = afwGeom.Point2D(15000, 4000) scale = 1 * afwGeom.arcseconds cdMatrix = afwGeom.makeCdMatrix(scale=scale, flipX=True) self.tanWcs = afwGeom.makeSkyWcs(crpix=crpix, crval=crval, cdMatrix=cdMatrix) self.loadData()
def setUp(self): # Test geometry: # # -100,99 99,99 # +--------------------+ # |AAAAAAAAAACCCCCDDDDD| A == only in epoch A # |AAAAAAAAAACCCCCDDDDD| B == only in epoch B # |AAAAAAAAAACCCCCDDDDD| C == in both epoch A and epoch B # |AAAAAAAAAACCCCCDDDDD| D == in epoch A; in B's bbox but outside its ValidPolygon # |AAAAAAAAAACCCCCDDDDD| # | BBBBBBBBBB| All WCSs have the same CRVAL and CD. # | BBBBBBBBBB| # | BBBBBBBBBB| Coadd has CRPIX=(0, 0) # | BBBBBBBBBB| Epoch A has CRPIX=(0, -50) # | BBBBBBBBBB| Epoch B has CRPIX=(-50, 0) # +--------------------+ # -100,-100 99,-100 # self.rng = np.random.RandomState(50) crval = SpherePoint(45.0, 45.0, degrees) cdMatrix = makeCdMatrix(scale=5E-5 * degrees, flipX=True) self.wcsCoadd = makeSkyWcs(crpix=Point2D(0.0, 0.0), crval=crval, cdMatrix=cdMatrix) self.wcsA = makeSkyWcs(crpix=Point2D(0.0, -50.0), crval=crval, cdMatrix=cdMatrix) self.wcsB = makeSkyWcs(crpix=Point2D(-50.0, 0.0), crval=crval, cdMatrix=cdMatrix) self.bboxCoadd = Box2I(Point2I(-100, -100), Point2I(99, 99)) self.bboxA = Box2I(Point2I(-100, -50), Point2I(99, 49)) self.bboxB = Box2I(Point2I(-50, -100), Point2I(49, 99)) self.polygonA = None polygonD = Polygon(Box2D(Box2I(Point2I(0, 0), Point2I(49, 99)))) self.polygonB, = polygonD.symDifference(Polygon(Box2D(self.bboxB))) self.curveA = makeRandomTransmissionCurve(self.rng) self.curveB = makeRandomTransmissionCurve(self.rng) self.weightA = 0.6 self.weightB = 0.2 schema = ExposureTable.makeMinimalSchema() weightKey = schema.addField("weight", type=float, doc="relative weight of image in Coadd") catalog = ExposureCatalog(schema) recordA = catalog.addNew() recordA[weightKey] = self.weightA recordA.setWcs(self.wcsA) recordA.setValidPolygon(self.polygonA) recordA.setBBox(self.bboxA) recordA.setTransmissionCurve(self.curveA) recordB = catalog.addNew() recordB[weightKey] = self.weightB recordB.setWcs(self.wcsB) recordB.setValidPolygon(self.polygonB) recordB.setBBox(self.bboxB) recordB.setTransmissionCurve(self.curveB) self.curveCoadd = makeCoaddTransmissionCurve(self.wcsCoadd, catalog)
def setUp(self): # Construct an arbitrary WCS for testing. crval = lsst.geom.SpherePoint(45.0, 45.0, lsst.geom.degrees) scale = 0.2 * lsst.geom.arcseconds crpix = lsst.geom.PointD(100, 100) self.wcs = afwGeom.makeSkyWcs( crpix=crpix, crval=crval, cdMatrix=afwGeom.makeCdMatrix(scale=scale))
def setUp(self): scale = 5.55555555e-05*lsst.geom.degrees self.cdMatrix = afwGeom.makeCdMatrix(scale=scale, flipX=True) self.crpix = lsst.geom.PointD(1000, 1000) self.crval = lsst.geom.SpherePoint(0.0, 0.0, lsst.geom.degrees) self.wcsref = afwGeom.makeSkyWcs(crpix=self.crpix, crval=self.crval, cdMatrix=self.cdMatrix) schema = afwTable.ExposureTable.makeMinimalSchema() self.weightKey = schema.addField("weight", type="D", doc="Coadd weight") self.mycatalog = afwTable.ExposureCatalog(schema)
def __init__(self, pixelScale, projection, rotation=0 * geom.radians, flipX=False): if len(projection) != 3: raise RuntimeError("projection=%r; must have length 3" % (projection, )) self._projection = projection self._cdMatrix = afwGeom.makeCdMatrix(scale=pixelScale, orientation=rotation, flipX=flipX)
def makeGalaxy(width, height, flux, a, b, theta, dx=0.0, dy=0.0, xy0=None, xcen=None, ycen=None): """Make a fake galaxy image. """ gal = afwImage.ImageF(width, height) if xcen is None: xcen = 0.5*width + dx if ycen is None: ycen = 0.5*height + dy I0 = flux/(2*math.pi*a*b) if xy0 is not None: gal.setXY0(xy0) c, s = math.cos(math.radians(theta)), math.sin(math.radians(theta)) ii, iuu, ivv = 0.0, 0.0, 0.0 for y in range(height): for x in range(width): dx, dy = x + gal.getX0() - xcen, y + gal.getY0() - ycen if math.hypot(dx, dy) < 10.5: nsample = 5 subZ = np.linspace(-0.5*(1 - 1/nsample), 0.5*(1 - 1/nsample), nsample) else: nsample = 1 subZ = [0.0] val = 0 for sx in subZ: for sy in subZ: u = c*(dx + sx) + s*(dy + sy) v = -s*(dx + sx) + c*(dy + sy) val += I0*math.exp(-0.5*((u/a)**2 + (v/b)**2)) if val < 0: val = 0 gal[afwGeom.Point2I(x, y), afwImage.LOCAL] = val/nsample**2 ii += val iuu += val*u**2 ivv += val*v**2 iuu /= ii ivv /= ii exp = afwImage.makeExposure(afwImage.makeMaskedImage(gal)) exp.getMaskedImage().getVariance().set(1.0) scale = 1.0e-4*afwGeom.degrees cdMatrix = afwGeom.makeCdMatrix(scale=scale, flipX=True) exp.setWcs(afwGeom.makeSkyWcs(crpix=afwGeom.Point2D(0.0, 0.0), crval=afwGeom.SpherePoint(0.0, 0.0, afwGeom.degrees), cdMatrix=cdMatrix)) # add a dummy Psf. The new SdssCentroid needs one exp.setPsf(afwDetection.GaussianPsf(11, 11, 0.01)) return exp
def setUp(self): self.config = measAstrom.MatchOptimisticBTask.ConfigClass() self.matchOptimisticB = measAstrom.MatchOptimisticBTask(config=self.config) self.wcs = afwGeom.makeSkyWcs(crpix=lsst.geom.Point2D(791.4, 559.7), crval=lsst.geom.SpherePoint(36.930640, -4.939560, lsst.geom.degrees), cdMatrix=afwGeom.makeCdMatrix(scale=5.17e-5*lsst.geom.degrees)) self.distortedWcs = self.wcs self.filename = os.path.join(os.path.dirname(__file__), "cat.xy.fits") self.tolArcsec = .4 self.tolPixel = .1
def testGetFrameDict(self): """Test that getFrameDict returns a deep copy """ cdMatrix = makeCdMatrix(scale=self.scale) skyWcs = makeSkyWcs(crpix=self.crpix, crval=self.crvalList[0], cdMatrix=cdMatrix) for domain in ("PIXELS", "IWC", "SKY"): frameDict = skyWcs.getFrameDict() frameDict.removeFrame(domain) self.assertFalse(frameDict.hasDomain(domain)) self.assertTrue(skyWcs.getFrameDict().hasDomain(domain))
def testMaskedImage(self): scale = 1.0*lsst.geom.arcseconds wcs = afwGeom.makeSkyWcs(crval=lsst.geom.SpherePoint(0.0*lsst.geom.degrees, 0.0*lsst.geom.degrees), crpix=lsst.geom.Point2D(0.0, 0.0), cdMatrix=afwGeom.makeCdMatrix(scale=scale)) for MaskedImage in (afwImage.MaskedImageF, afwImage.MaskedImageD, ): image = self.createMaskedImage(MaskedImage) self.checkMaskedImages(image) exposure = afwImage.makeExposure(image, wcs) self.checkExposures(exposure)
def setUp(self): self.config = measAstrom.MatchOptimisticBTask.ConfigClass() self.matchOptimisticB = measAstrom.MatchOptimisticBTask(config=self.config) self.wcs = afwGeom.makeSkyWcs(crpix=lsst.geom.Point2D(791.4, 559.7), crval=lsst.geom.SpherePoint(36.930640, -4.939560, lsst.geom.degrees), cdMatrix=afwGeom.makeCdMatrix(scale=5.17e-5*lsst.geom.degrees)) self.distortedWcs = self.wcs self.filename = os.path.join(os.path.dirname(__file__), "cat.xy.fits") self.tolArcsec = .4 self.tolPixel = .1
def setUp(self): self.config = MakeDiscreteSkyMapConfig() self.task = MakeDiscreteSkyMapTask(config=self.config) self.cd_matrix = afwGeom.makeCdMatrix(scale=0.2*lsst.geom.arcseconds) self.crpix = lsst.geom.Point2D(100, 100) self.crval1 = lsst.geom.SpherePoint(10.0*lsst.geom.degrees, 0.0*lsst.geom.degrees) self.wcs1 = afwGeom.makeSkyWcs(crpix=self.crpix, crval=self.crval1, cdMatrix=self.cd_matrix) self.bbox = lsst.geom.Box2I(corner=lsst.geom.Point2I(0, 0), dimensions=lsst.geom.Extent2I(200, 200)) self.crval2 = lsst.geom.SpherePoint(11.0*lsst.geom.degrees, 1.0*lsst.geom.degrees) self.wcs2 = afwGeom.makeSkyWcs(crpix=self.crpix, crval=self.crval2, cdMatrix=self.cd_matrix) self.crval3 = lsst.geom.SpherePoint(20.0*lsst.geom.degrees, 10.0*lsst.geom.degrees) self.wcs3 = afwGeom.makeSkyWcs(crpix=self.crpix, crval=self.crval3, cdMatrix=self.cd_matrix)
def setUp(self): refCatDir = os.path.join(os.path.dirname(__file__), "data", "sdssrefcat") self.bbox = afwGeom.Box2I(afwGeom.Point2I(0, 0), afwGeom.Extent2I(3001, 3001)) crpix = afwGeom.Box2D(self.bbox).getCenter() self.tanWcs = afwGeom.makeSkyWcs(crpix=crpix, crval=afwGeom.SpherePoint(215.5, 53.0, afwGeom.degrees), cdMatrix=afwGeom.makeCdMatrix(scale=5.1e-5*afwGeom.degrees)) self.exposure = afwImage.ExposureF(self.bbox) self.exposure.setWcs(self.tanWcs) self.exposure.setFilter(afwImage.Filter("r", True)) butler = Butler(refCatDir) self.refObjLoader = LoadIndexedReferenceObjectsTask(butler=butler)
def testTicket2441(self): """Test ticket 2441: warpExposure sometimes mishandles zero-extent dest exposures""" fromWcs = afwGeom.makeSkyWcs( crpix=afwGeom.Point2D(0, 0), crval=afwGeom.SpherePoint(359, 0, afwGeom.degrees), cdMatrix=afwGeom.makeCdMatrix(scale=1.0e-8*afwGeom.degrees), ) fromExp = afwImage.ExposureF(afwImage.MaskedImageF(10, 10), fromWcs) toWcs = afwGeom.makeSkyWcs( crpix=afwGeom.Point2D(410000, 11441), crval=afwGeom.SpherePoint(45, 0, afwGeom.degrees), cdMatrix=afwGeom.makeCdMatrix(scale=0.00011*afwGeom.degrees, flipX=True), projection="CEA", ) toExp = afwImage.ExposureF(afwImage.MaskedImageF(0, 0), toWcs) warpControl = afwMath.WarpingControl("lanczos3") # if a bug described in ticket #2441 is present, this will raise an # exception: numGoodPix = afwMath.warpExposure(toExp, fromExp, warpControl) self.assertEqual(numGoodPix, 0)
def setUp(self): refCatDir = os.path.join(os.path.dirname(__file__), "data", "sdssrefcat") self.bbox = lsst.geom.Box2I(lsst.geom.Point2I(0, 0), lsst.geom.Extent2I(3001, 3001)) crpix = lsst.geom.Box2D(self.bbox).getCenter() self.tanWcs = afwGeom.makeSkyWcs(crpix=crpix, crval=lsst.geom.SpherePoint(215.5, 53.0, lsst.geom.degrees), cdMatrix=afwGeom.makeCdMatrix(scale=5.1e-5*lsst.geom.degrees)) self.exposure = afwImage.ExposureF(self.bbox) self.exposure.setWcs(self.tanWcs) self.exposure.setFilter(afwImage.Filter("r", True)) butler = Butler(refCatDir) self.refObjLoader = LoadIndexedReferenceObjectsTask(butler=butler)
def testTicket2441(self): """Test ticket 2441: warpExposure sometimes mishandles zero-extent dest exposures""" fromWcs = afwGeom.makeSkyWcs( crpix=lsst.geom.Point2D(0, 0), crval=lsst.geom.SpherePoint(359, 0, lsst.geom.degrees), cdMatrix=afwGeom.makeCdMatrix(scale=1.0e-8*lsst.geom.degrees), ) fromExp = afwImage.ExposureF(afwImage.MaskedImageF(10, 10), fromWcs) toWcs = afwGeom.makeSkyWcs( crpix=lsst.geom.Point2D(410000, 11441), crval=lsst.geom.SpherePoint(45, 0, lsst.geom.degrees), cdMatrix=afwGeom.makeCdMatrix(scale=0.00011*lsst.geom.degrees, flipX=True), projection="CEA", ) toExp = afwImage.ExposureF(afwImage.MaskedImageF(0, 0), toWcs) warpControl = afwMath.WarpingControl("lanczos3") # if a bug described in ticket #2441 is present, this will raise an # exception: numGoodPix = afwMath.warpExposure(toExp, fromExp, warpControl) self.assertEqual(numGoodPix, 0)
def setUp(self): # Set up a Coadd with CoaddInputs tables that have blank filter # columns to be filled in by later test code. self.coadd = ExposureF(30, 90) # WCS is arbitrary, since it'll be the same for all images wcs = makeSkyWcs(crpix=Point2D(0, 0), crval=SpherePoint(45.0, 45.0, degrees), cdMatrix=makeCdMatrix(scale=0.17 * degrees)) self.coadd.setWcs(wcs) schema = ExposureCatalog.Table.makeMinimalSchema() self.filterKey = schema.addField("filter", type=str, doc="", size=16) weightKey = schema.addField("weight", type=float, doc="") # First input image covers the first 2/3, second covers the last 2/3, # so they overlap in the middle 1/3. inputs = ExposureCatalog(schema) self.input1 = inputs.addNew() self.input1.setId(1) self.input1.setBBox(Box2I(Point2I(0, 0), Point2I(29, 59))) self.input1.setWcs(wcs) self.input1.set(weightKey, 2.0) self.input2 = inputs.addNew() self.input2.setId(2) self.input2.setBBox(Box2I(Point2I(0, 30), Point2I(29, 89))) self.input2.setWcs(wcs) self.input2.set(weightKey, 3.0) # Use the same catalog for visits and CCDs since the algorithm we're # testing only cares about CCDs. self.coadd.getInfo().setCoaddInputs(CoaddInputs(inputs, inputs)) # Set up a catalog with centroids and a FilterFraction plugin. # We have one record in each region (first input only, both inputs, # second input only) schema = SourceCatalog.Table.makeMinimalSchema() centroidKey = Point2DKey.addFields(schema, "centroid", doc="position", unit="pixel") schema.getAliasMap().set("slot_Centroid", "centroid") self.plugin = FilterFractionPlugin( config=FilterFractionPlugin.ConfigClass(), schema=schema, name="subaru_FilterFraction", metadata=PropertyList()) catalog = SourceCatalog(schema) self.record1 = catalog.addNew() self.record1.set(centroidKey, Point2D(14.0, 14.0)) self.record12 = catalog.addNew() self.record12.set(centroidKey, Point2D(14.0, 44.0)) self.record2 = catalog.addNew() self.record2.set(centroidKey, Point2D(14.0, 74.0))
def setUp(self): # Test geometry: # # -100,99 99,99 # +--------------------+ # |AAAAAAAAAACCCCCDDDDD| A == only in epoch A # |AAAAAAAAAACCCCCDDDDD| B == only in epoch B # |AAAAAAAAAACCCCCDDDDD| C == in both epoch A and epoch B # |AAAAAAAAAACCCCCDDDDD| D == in epoch A; in B's bbox but outside its ValidPolygon # |AAAAAAAAAACCCCCDDDDD| # | BBBBBBBBBB| All WCSs have the same CRVAL and CD. # | BBBBBBBBBB| # | BBBBBBBBBB| Coadd has CRPIX=(0, 0) # | BBBBBBBBBB| Epoch A has CRPIX=(0, -50) # | BBBBBBBBBB| Epoch B has CRPIX=(-50, 0) # +--------------------+ # -100,-100 99,-100 # self.rng = np.random.RandomState(50) crval = SpherePoint(45.0, 45.0, degrees) cdMatrix = makeCdMatrix(scale=5E-5*degrees, flipX=True) self.wcsCoadd = makeSkyWcs(crpix=Point2D(0.0, 0.0), crval=crval, cdMatrix=cdMatrix) self.wcsA = makeSkyWcs(crpix=Point2D(0.0, -50.0), crval=crval, cdMatrix=cdMatrix) self.wcsB = makeSkyWcs(crpix=Point2D(-50.0, 0.0), crval=crval, cdMatrix=cdMatrix) self.bboxCoadd = Box2I(Point2I(-100, -100), Point2I(99, 99)) self.bboxA = Box2I(Point2I(-100, -50), Point2I(99, 49)) self.bboxB = Box2I(Point2I(-50, -100), Point2I(49, 99)) self.polygonA = None polygonD = Polygon(Box2D(Box2I(Point2I(0, 0), Point2I(49, 99)))) self.polygonB, = polygonD.symDifference(Polygon(Box2D(self.bboxB))) self.curveA = makeRandomTransmissionCurve(self.rng) self.curveB = makeRandomTransmissionCurve(self.rng) self.weightA = 0.6 self.weightB = 0.2 schema = ExposureTable.makeMinimalSchema() weightKey = schema.addField("weight", type=float, doc="relative weight of image in Coadd") catalog = ExposureCatalog(schema) recordA = catalog.addNew() recordA[weightKey] = self.weightA recordA.setWcs(self.wcsA) recordA.setValidPolygon(self.polygonA) recordA.setBBox(self.bboxA) recordA.setTransmissionCurve(self.curveA) recordB = catalog.addNew() recordB[weightKey] = self.weightB recordB.setWcs(self.wcsB) recordB.setValidPolygon(self.polygonB) recordB.setBBox(self.bboxB) recordB.setTransmissionCurve(self.curveB) self.curveCoadd = makeCoaddTransmissionCurve(self.wcsCoadd, catalog)
def createImage( dataId={"name": "foobar"}, # Data identifier center=CENTER, # ICRS sky position of center (lsst.afw.geom.SpherePoint) rotateAxis=ROTATEAXIS, # Rotation axis (lsst.afw.geom.SpherePoint) rotateAngle=0*afwGeom.degrees, # Rotation angle/distance to move (Angle) dims=DIMS, # Image dimensions (Extent2I) scale=SCALE # Pixel scale (Angle) ): crpix = afwGeom.Point2D(afwGeom.Extent2D(dims)*0.5) center = center.rotated(rotateAxis, rotateAngle) cdMatrix = afwGeom.makeCdMatrix(scale=scale) wcs = afwGeom.makeSkyWcs(crpix=crpix, crval=center, cdMatrix=cdMatrix) return SelectStruct(DummyDataRef(dataId), wcs, afwGeom.Box2I(afwGeom.Point2I(0, 0), afwGeom.Extent2I(dims[0], dims[1])))
def setUp(self): xy0 = Point2I(12345, 67890) # xy0 for image dims = Extent2I(2345, 2345) # Dimensions of image box = Box2I(xy0, dims) # Bounding box of image sigma = 3.21 # PSF sigma buffer = 4.0 # Buffer for star centers around edge nSigmaForKernel = 5.0 # Number of PSF sigmas for kernel sky = 12345.6 # Sky level numStars = 100 # Number of stars noise = np.sqrt(sky) * np.pi * sigma**2 # Poisson noise per PSF faint = 1.0 * noise # Faintest level for star fluxes bright = 100.0 * noise # Brightest level for star fluxes starBox = Box2I(box) # Area on image in which we can put star centers starBox.grow(-int(buffer * sigma)) scale = 1.0e-5 * degrees # Pixel scale np.random.seed(12345) stars = [(xx, yy, ff, sigma) for xx, yy, ff in zip( np.random.uniform(starBox.getMinX(), starBox.getMaxX(), numStars), np.random.uniform(starBox.getMinY(), starBox.getMaxY(), numStars), np.linspace(faint, bright, numStars))] self.exposure = plantSources(box, 2 * int(nSigmaForKernel * sigma) + 1, sky, stars, True) self.exposure.setWcs( makeSkyWcs(crpix=Point2D(0, 0), crval=SpherePoint(0, 0, degrees), cdMatrix=makeCdMatrix(scale=scale))) # Make a large area of extra background; we should be robust against it # Unfortunately, some tuning is required here to get something challenging but not impossible: # * A very large box will cause failures because the "extra" and the "normal" are reversed. # * A small box will not be challenging because it's simple to clip out. # * A large value will cause failures because it produces large edges in background-subtrction that # broaden flux distributions. # * A small value will not be challenging because it has little effect. extraBox = Box2I(xy0 + Extent2I(345, 456), Extent2I(1234, 1234)) # Box for extra background extraValue = 0.5 * noise # Extra background value to add in self.exposure.image[extraBox, PARENT] += extraValue self.config = DynamicDetectionTask.ConfigClass() self.config.skyObjects.nSources = 300 self.config.reEstimateBackground = False self.config.doTempWideBackground = True self.config.thresholdType = "pixel_stdev" # Relative tolerance for tweak factor # Not sure why this isn't smaller; maybe due to use of Poisson instead of Gaussian noise? self.rtol = 0.1
def createPatch( tractId=1, patchId=(2, 3), # Tract and patch identifier, for dataId dims=DIMS, # Patch dimensions (Extent2I) xy0=afwGeom.Point2I(1234, 5678), # Patch xy0 (Point2I) center=CENTER, # ICRS sky position of center (lsst.afw.geom.SpherePoint) scale=SCALE # Pixel scale (Angle) ): crpix = afwGeom.Point2D(xy0) + afwGeom.Extent2D(dims)*0.5 cdMatrix = afwGeom.makeCdMatrix(scale=scale) wcs = afwGeom.makeSkyWcs(crpix=crpix, crval=center, cdMatrix=cdMatrix) patch = DummyPatch(xy0, dims) tract = DummyTract(patchId, patch, wcs) skymap = DummySkyMap(tractId, tract) dataRef = DummyDataRef({'tract': tractId, 'patch': ",".join(map(str, patchId))}, deepCoadd_skyMap=skymap) return dataRef
def setUp(self): self.datapath = setupAstrometryNetDataDir('photocal') self.bbox = lsst.geom.Box2I(lsst.geom.Point2I(0, 0), lsst.geom.Extent2I(3001, 3001)) crpix = lsst.geom.Box2D(self.bbox).getCenter() self.tanWcs = afwGeom.makeSkyWcs(crpix=crpix, crval=lsst.geom.SpherePoint(215.5, 53.0, lsst.geom.degrees), cdMatrix=afwGeom.makeCdMatrix(scale=5.1e-5*lsst.geom.degrees)) self.exposure = afwImage.ExposureF(self.bbox) self.exposure.setWcs(self.tanWcs) self.exposure.setFilter(afwImage.Filter("r", True)) andConfig = AstrometryNetDataConfig() andConfig.load(os.path.join(self.datapath, 'andConfig2.py')) andConfig.magErrorColumnMap = {} self.refObjLoader = LoadAstrometryNetObjectsTask(andConfig=andConfig)
def test_loadPixelBox(self): """Test the loadPixelBox routine.""" # This will create a box 50 degrees on a side. loaderConfig = ReferenceObjectLoader.ConfigClass() loaderConfig.pixelMargin = 0 loader = ReferenceObjectLoader( [dataRef.dataId for dataRef in self.datasetRefs], self.handles, config=loaderConfig) bbox = lsst.geom.Box2I(corner=lsst.geom.Point2I(0, 0), dimensions=lsst.geom.Extent2I(1000, 1000)) crpix = lsst.geom.Point2D(500, 500) crval = lsst.geom.SpherePoint(180.0 * lsst.geom.degrees, 0.0 * lsst.geom.degrees) cdMatrix = afwGeom.makeCdMatrix(scale=0.05 * lsst.geom.degrees) wcs = afwGeom.makeSkyWcs(crpix=crpix, crval=crval, cdMatrix=cdMatrix) cat = loader.loadPixelBox(bbox, wcs, 'a', bboxToSpherePadding=0).refCat # This is a sanity check on the ranges; the exact selection depends # on cos(dec) and the tangent-plane projection. self.assertLess(np.max(np.rad2deg(cat['coord_ra'])), 180.0 + 25.0) self.assertGreater(np.max(np.rad2deg(cat['coord_ra'])), 180.0 - 25.0) self.assertLess(np.max(np.rad2deg(cat['coord_dec'])), 25.0) self.assertGreater(np.min(np.rad2deg(cat['coord_dec'])), -25.0) # The following is to ensure the reference catalog coords are # getting corrected for proper motion when an epoch is provided. # Use an extreme epoch so that differences in corrected coords # will be significant. Note that this simply tests that the coords # do indeed change when the epoch is passed. It makes no attempt # at assessing the correctness of the change. This is left to the # explicit testProperMotion() test below. catWithEpoch = loader.loadPixelBox(bbox, wcs, 'a', bboxToSpherePadding=0, epoch=astropy.time.Time( 30000, format='mjd', scale='tai')).refCat self.assertFloatsNotEqual(cat['coord_ra'], catWithEpoch['coord_ra'], rtol=1.0e-4) self.assertFloatsNotEqual(cat['coord_dec'], catWithEpoch['coord_dec'], rtol=1.0e-4)
def makeExposure(bbox, scale, psfFwhm, flux): """Make a fake exposure Parameters ---------- bbox : `lsst.afw.geom.Box2I` Bounding box for image. scale : `lsst.afw.geom.Angle` Pixel scale. psfFwhm : `float` PSF FWHM (arcseconds) flux : `float` PSF flux (ADU) Returns ------- exposure : `lsst.afw.image.ExposureF` Fake exposure. center : `lsst.afw.geom.Point2D` Position of fake source. """ image = afwImage.ImageF(bbox) image.set(0) center = afwGeom.Box2D(bbox).getCenter() psfSigma = psfFwhm / SIGMA_TO_FWHM / scale.asArcseconds() psfWidth = 2 * int(4.0 * psfSigma) + 1 psf = afwDetection.GaussianPsf(psfWidth, psfWidth, psfSigma) psfImage = psf.computeImage(center).convertF() psfFlux = psfImage.getArray().sum() psfImage *= flux / psfFlux subImage = afwImage.ImageF(image, psfImage.getBBox(afwImage.PARENT), afwImage.PARENT) subImage += psfImage exp = afwImage.makeExposure(afwImage.makeMaskedImage(image)) exp.setPsf(psf) exp.getMaskedImage().getVariance().set(1.0) exp.getMaskedImage().getMask().set(0) cdMatrix = afwGeom.makeCdMatrix(scale=scale) exp.setWcs( afwGeom.makeSkyWcs(crpix=center, crval=afwGeom.SpherePoint(0.0, 0.0, afwGeom.degrees), cdMatrix=cdMatrix)) return exp, center
def getWcs(self): r"""Construct a dummy WCS object. Taken from the deprecated ip_isr/examples/exampleUtils.py. This is not guaranteed, given the distortion and pixel scale listed in the afwTestUtils camera definition. Returns ------- wcs : `lsst.afw.geom.SkyWcs` Test WCS transform. """ return afwGeom.makeSkyWcs(crpix=afwGeom.Point2D(0.0, 100.0), crval=afwGeom.SpherePoint(45.0, 25.0, afwGeom.degrees), cdMatrix=afwGeom.makeCdMatrix(scale=1.0*afwGeom.degrees))
def createImage( dataId={"name": "foobar"}, # Data identifier center=CENTER, # ICRS sky position of center (lsst.afw.geom.SpherePoint) rotateAxis=ROTATEAXIS, # Rotation axis (lsst.afw.geom.SpherePoint) rotateAngle=0 * geom.degrees, # Rotation angle/distance to move (Angle) dims=DIMS, # Image dimensions (Extent2I) scale=SCALE # Pixel scale (Angle) ): crpix = geom.Point2D(geom.Extent2D(dims) * 0.5) center = center.rotated(rotateAxis, rotateAngle) cdMatrix = afwGeom.makeCdMatrix(scale=scale) wcs = afwGeom.makeSkyWcs(crpix=crpix, crval=center, cdMatrix=cdMatrix) return SelectStruct( DummyDataRef(dataId), wcs, geom.Box2I(geom.Point2I(0, 0), geom.Extent2I(dims[0], dims[1])))
def getWcs(self): """Construct a dummy WCS object. Taken from the deprecated ip_isr/examples/exampleUtils.py. This is not guaranteed, given the distortion and pixel scale listed in the afwTestUtils camera definition. Returns ------- wcs : `lsst.afw.geom.SkyWcs` Test WCS transform. """ return afwGeom.makeSkyWcs(crpix=lsst.geom.Point2D(0.0, 100.0), crval=lsst.geom.SpherePoint(45.0, 25.0, lsst.geom.degrees), cdMatrix=afwGeom.makeCdMatrix(scale=1.0*lsst.geom.degrees))
def _preparePlugin(self, addCoaddInputs): """Prepare a `SingleFrameInputCountPlugin` for running. Sets up the plugin to run on an empty catalog together with a synthetic, content-free `~lsst.afw.image.ExposureF`. Parameters ---------- addCoaddInputs : `bool` Should we add the coadd inputs? Returns ------- inputCount : `SingleFrameInputCountPlugin` Initialized measurement plugin. catalog : `lsst.afw.table.SourceCatalog` Empty Catalog. exp : `lsst.afw.image.ExposureF` Synthetic exposure. """ exp = afwImage.ExposureF(20, 20) scale = 1.0e-5 * lsst.geom.degrees wcs = afwGeom.makeSkyWcs(crpix=lsst.geom.Point2D(0, 0), crval=lsst.geom.SpherePoint( 0.0, 0.0, lsst.geom.degrees), cdMatrix=afwGeom.makeCdMatrix(scale=scale)) exp.setWcs(wcs) if addCoaddInputs: exp.getInfo().setCoaddInputs( afwImage.CoaddInputs( afwTable.ExposureTable.makeMinimalSchema(), afwTable.ExposureTable.makeMinimalSchema())) ccds = exp.getInfo().getCoaddInputs().ccds record = ccds.addNew() record.setWcs(wcs) record.setBBox(exp.getBBox()) record.setValidPolygon( afwGeom.Polygon(lsst.geom.Box2D(exp.getBBox()))) schema = afwTable.SourceTable.makeMinimalSchema() measBase.SingleFramePeakCentroidPlugin( measBase.SingleFramePeakCentroidConfig(), "centroid", schema, None) schema.getAliasMap().set("slot_Centroid", "centroid") inputCount = measBase.SingleFrameInputCountPlugin( measBase.InputCountConfig(), "inputCount", schema, None) catalog = afwTable.SourceCatalog(schema) return inputCount, catalog, exp
def setUp(self): xy0 = Point2I(12345, 67890) # xy0 for image dims = Extent2I(2345, 2345) # Dimensions of image box = Box2I(xy0, dims) # Bounding box of image sigma = 3.21 # PSF sigma buffer = 4.0 # Buffer for star centers around edge nSigmaForKernel = 5.0 # Number of PSF sigmas for kernel sky = 12345.6 # Sky level numStars = 100 # Number of stars noise = np.sqrt(sky)*np.pi*sigma**2 # Poisson noise per PSF faint = 1.0*noise # Faintest level for star fluxes bright = 100.0*noise # Brightest level for star fluxes starBox = Box2I(box) # Area on image in which we can put star centers starBox.grow(-int(buffer*sigma)) scale = 1.0e-5*degrees # Pixel scale np.random.seed(12345) stars = [(xx, yy, ff, sigma) for xx, yy, ff in zip(np.random.uniform(starBox.getMinX(), starBox.getMaxX(), numStars), np.random.uniform(starBox.getMinY(), starBox.getMaxY(), numStars), np.linspace(faint, bright, numStars))] self.exposure = plantSources(box, 2*int(nSigmaForKernel*sigma) + 1, sky, stars, True) self.exposure.setWcs(makeSkyWcs(crpix=Point2D(0, 0), crval=SpherePoint(0, 0, degrees), cdMatrix=makeCdMatrix(scale=scale))) # Make a large area of extra background; we should be robust against it # Unfortunately, some tuning is required here to get something challenging but not impossible: # * A very large box will cause failures because the "extra" and the "normal" are reversed. # * A small box will not be challenging because it's simple to clip out. # * A large value will cause failures because it produces large edges in background-subtrction that # broaden flux distributions. # * A small value will not be challenging because it has little effect. extraBox = Box2I(xy0 + Extent2I(345, 456), Extent2I(1234, 1234)) # Box for extra background extraValue = 0.5*noise # Extra background value to add in self.exposure.image[extraBox, PARENT] += extraValue self.config = DynamicDetectionTask.ConfigClass() self.config.skyObjects.nSources = 300 self.config.reEstimateBackground = False self.config.doTempWideBackground = True self.config.thresholdType = "pixel_stdev" # Relative tolerance for tweak factor # Not sure why this isn't smaller; maybe due to use of Poisson instead of Gaussian noise? self.rtol = 0.1
def setUp(self): '''Create two calibs, one with a valid zero-point and one without. Use these to create two UnitSystem objects. ''' self.mag2Flux = lambda m: 10.0**(m/2.5) self.flux2Mag = lambda f: 2.5*np.log10(f) photoCalibNoZero = afwImage.PhotoCalib() photoCalibWithZero = afwImage.makePhotoCalibFromCalibZeroPoint(self.mag2Flux(25)) scale = 0.2 * geom.arcseconds wcs = afwGeom.makeSkyWcs(crpix=geom.Point2D(), crval=geom.SpherePoint(45.0, 45.0, geom.degrees), cdMatrix=afwGeom.makeCdMatrix(scale=scale)) self.unitNoZero = measModel.UnitSystem(wcs, photoCalibNoZero) self.unitWithZero = measModel.UnitSystem(wcs, photoCalibWithZero)
def setUp(self): '''Create two calibs, one with a valid zero-point and one without. Use these to create two UnitSystem objects. ''' self.mag2Flux = lambda m: 10.0**(m/2.5) self.flux2Mag = lambda f: 2.5*np.log10(f) photoCalibNoZero = afwImage.PhotoCalib() photoCalibWithZero = afwImage.makePhotoCalibFromCalibZeroPoint(self.mag2Flux(25)) scale = 0.2 * afwGeom.arcseconds wcs = afwGeom.makeSkyWcs(crpix=afwGeom.Point2D(), crval=afwGeom.SpherePoint(45.0, 45.0, afwGeom.degrees), cdMatrix=afwGeom.makeCdMatrix(scale=scale)) self.unitNoZero = measModel.UnitSystem(wcs, photoCalibNoZero) self.unitWithZero = measModel.UnitSystem(wcs, photoCalibWithZero)
def makeMetadata(self): """Return a WCS that is typical for an image It will contain 32 cards: - 14 standard WCS cards - 15 standard cards: - SIMPLE, BITPIX, NAXIS, NAXIS1, NAXIS2, BZERO, BSCALE - DATE-OBS, MJD-OBS, TIMESYS - EXPTIME - 2 COMMENT cards - INHERIT - EXTEND - LTV1 and LTV2, an IRAF convention LSST uses for image XY0 - 1 nonstandard card """ # arbitrary values orientation = 0 * degrees flipX = False metadata = makeTanWcsMetadata( crpix=self.crpix, crval=self.crval, cdMatrix=makeCdMatrix(scale=self.scale, orientation=orientation, flipX=flipX), ) self.assertEqual(metadata.nameCount(), 14) metadata.add("SIMPLE", True) metadata.add("BITPIX", 16) metadata.add("NAXIS", 2) metadata.add("NAXIS1", 500) metadata.add("NAXIS2", 200) metadata.add("BZERO", 32768) metadata.add("BSCALE", 1) metadata.add("TIMESYS", "UTC") metadata.add("UTC-OBS", "12:04:45.73") metadata.add("DATE-OBS", "2006-05-20") metadata.add("EXPTIME", 5.0) metadata.add("COMMENT", "a comment") metadata.add("COMMENT", "another comment") metadata.add("EXTEND", True) metadata.add("INHERIT", False) metadata.add("LTV1", 5) metadata.add("LTV2", -10) metadata.add("ZOTHER", "non-standard") return metadata
def makeMetadata(self): """Return a WCS that is typical for an image It will contain 14 cards that describe a WCS, added by makeSimpleWcsMetadata, plus 25 additional cards, including a set for WCS "A", which is what LSST uses to store xy0, and LTV1 and LTV2, which LSST used to use for xy0 """ # arbitrary values orientation = 0 * degrees flipX = False metadata = makeSimpleWcsMetadata( crpix=self.crpix, crval=self.crval, cdMatrix=makeCdMatrix(scale=self.scale, orientation=orientation, flipX=flipX), ) self.assertEqual(metadata.nameCount(), 12) # 2 CD terms are zero and so are omitted metadata.add("SIMPLE", True) metadata.add("BITPIX", 16) metadata.add("NAXIS", 2) metadata.add("NAXIS1", 500) metadata.add("NAXIS2", 200) metadata.add("BZERO", 32768) metadata.add("BSCALE", 1) metadata.add("TIMESYS", "UTC") metadata.add("UTC-OBS", "12:04:45.73") metadata.add("DATE-OBS", "2006-05-20") metadata.add("EXPTIME", 5.0) metadata.add("COMMENT", "a comment") metadata.add("COMMENT", "another comment") metadata.add("HISTORY", "some history") metadata.add("EXTEND", True) metadata.add("INHERIT", False) metadata.add("CRPIX1A", 1.0) metadata.add("CRPIX2A", 1.0) metadata.add("CRVAL1A", 300) metadata.add("CRVAL2A", 400) metadata.add("CUNIT1A", "pixels") metadata.add("CUNIT2A", "pixels") metadata.add("LTV1", -300) metadata.add("LTV2", -400) metadata.add("ZOTHER", "non-standard") return metadata
def testLoadPixelBox(self): """Test LoadIndexedReferenceObjectsTask.loadPixelBox with default config.""" loader = LoadIndexedReferenceObjectsTask(butler=self.testButler) numFound = 0 for tupl, idList in self.compCats.items(): cent = make_coord(*tupl) bbox = lsst.geom.Box2I(lsst.geom.Point2I(30, -5), lsst.geom.Extent2I(1000, 1004)) # arbitrary ctr_pix = bbox.getCenter() # catalog is sparse, so set pixel scale such that bbox encloses region # used to generate compCats pixel_scale = 2*self.searchRadius/max(bbox.getHeight(), bbox.getWidth()) cdMatrix = afwGeom.makeCdMatrix(scale=pixel_scale) wcs = afwGeom.makeSkyWcs(crval=cent, crpix=ctr_pix, cdMatrix=cdMatrix) result = loader.loadPixelBox(bbox=bbox, wcs=wcs, filterName="a") self.assertFalse("camFlux" in result.refCat.schema) self.assertGreaterEqual(len(result.refCat), len(idList)) numFound += len(result.refCat) self.assertGreater(numFound, 0)
def testLoadPixelBox(self): """Test LoadIndexedReferenceObjectsTask.loadPixelBox with default config.""" loader = LoadIndexedReferenceObjectsTask(butler=self.testButler) numFound = 0 for tupl, idList in self.compCats.items(): cent = ingestIndexTestBase.make_coord(*tupl) bbox = lsst.geom.Box2I(lsst.geom.Point2I(30, -5), lsst.geom.Extent2I(1000, 1004)) # arbitrary ctr_pix = bbox.getCenter() # catalog is sparse, so set pixel scale such that bbox encloses region # used to generate compCats pixel_scale = 2*self.searchRadius/max(bbox.getHeight(), bbox.getWidth()) cdMatrix = afwGeom.makeCdMatrix(scale=pixel_scale) wcs = afwGeom.makeSkyWcs(crval=cent, crpix=ctr_pix, cdMatrix=cdMatrix) result = loader.loadPixelBox(bbox=bbox, wcs=wcs, filterName="a") self.assertFalse("camFlux" in result.refCat.schema) self.assertGreaterEqual(len(result.refCat), len(idList)) numFound += len(result.refCat) self.assertGreater(numFound, 0)
def setUp(self): crval = afwGeom.SpherePoint(44, 45, afwGeom.degrees) crpix = afwGeom.PointD(0, 0) scale = 1 * afwGeom.arcseconds self.tanWcs = afwGeom.makeSkyWcs( crpix=crpix, crval=crval, cdMatrix=afwGeom.makeCdMatrix(scale=scale)) S = 300 N = 5 if self.MatchClass == afwTable.ReferenceMatch: refSchema = LoadReferenceObjectsTask.makeMinimalSchema( filterNameList=["r"], addFluxSigma=True, addIsPhotometric=True) self.refCat = afwTable.SimpleCatalog(refSchema) elif self.MatchClass == afwTable.SourceMatch: refSchema = afwTable.SourceTable.makeMinimalSchema() self.refCat = afwTable.SourceCatalog(refSchema) else: raise RuntimeError("Unsupported MatchClass=%r" % (self.MatchClass, )) srcSchema = afwTable.SourceTable.makeMinimalSchema() SingleFrameMeasurementTask(schema=srcSchema) self.refCoordKey = afwTable.CoordKey(refSchema["coord"]) self.srcCoordKey = afwTable.CoordKey(srcSchema["coord"]) self.srcCentroidKey = afwTable.Point2DKey(srcSchema["slot_Centroid"]) self.sourceCat = afwTable.SourceCatalog(srcSchema) self.origSourceCat = afwTable.SourceCatalog( srcSchema) # undistorted copy self.matches = [] for i in np.linspace(0., S, N): for j in np.linspace(0., S, N): src = self.sourceCat.addNew() refObj = self.refCat.addNew() src.set(self.srcCentroidKey, afwGeom.Point2D(i, j)) c = self.tanWcs.pixelToSky(afwGeom.Point2D(i, j)) refObj.setCoord(c) self.matches.append(self.MatchClass(refObj, src, 0.0))
def setUp(self): self.camera = CameraWrapper().camera self.detector = DetectorWrapper().detector self.crpix = afwGeom.Point2D(50, 100) self.crval = afwGeom.SpherePoint(36, 71, afwGeom.degrees) scale = 1.0*afwGeom.arcseconds self.cdMatrix = afwGeom.makeCdMatrix(scale=scale) self.wcs = afwGeom.makeSkyWcs(crpix=self.crpix, crval=self.crval, cdMatrix=self.cdMatrix) self.bbox = afwGeom.Box2I(afwGeom.Point2I(-10, 10), afwGeom.Extent2I(1000, 1022)) self.exposure = ExposureF(self.bbox) # set the few items of ExposureInfo needed by IsrTask.run # when only adding a distortion model exposureInfo = ExposureInfo(photoCalib=PhotoCalib(1.0), detector=self.detector, visitInfo=VisitInfo(exposureTime=1.0), wcs=self.wcs) self.exposure.setInfo(exposureInfo)
def testMakeModifiedWcsNoActualPixels(self): """Test makeModifiedWcs on a SkyWcs that has no ACTUAL_PIXELS frame """ cdMatrix = makeCdMatrix(scale=self.scale) originalWcs = makeSkyWcs(crpix=self.crpix, crval=self.crvalList[0], cdMatrix=cdMatrix) originalFrameDict = originalWcs.getFrameDict() # make an arbitrary but reasonable transform to insert using makeModifiedWcs pixelTransform = makeRadialTransform([0.0, 1.0, 0.0, 0.0011]) # the result of the insertion should be as follows desiredPixelsToSky = pixelTransform.then(originalWcs.getTransform()) pixPointList = ( # arbitrary but reasonable Point2D(0.0, 0.0), Point2D(1000.0, 0.0), Point2D(0.0, 2000.0), Point2D(-1111.0, -2222.0), ) for modifyActualPixels in (False, True): modifiedWcs = makeModifiedWcs( pixelTransform=pixelTransform, wcs=originalWcs, modifyActualPixels=modifyActualPixels) modifiedFrameDict = modifiedWcs.getFrameDict() skyList = modifiedWcs.pixelToSky(pixPointList) # compare pixels to sky desiredSkyList = desiredPixelsToSky.applyForward(pixPointList) self.assertSpherePointListsAlmostEqual(skyList, desiredSkyList) # compare pixels to IWC pixelsToIwc = TransformPoint2ToPoint2( modifiedFrameDict.getMapping("PIXELS", "IWC")) desiredPixelsToIwc = TransformPoint2ToPoint2( pixelTransform.getMapping().then( originalFrameDict.getMapping("PIXELS", "IWC"))) self.assertPairListsAlmostEqual( pixelsToIwc.applyForward(pixPointList), desiredPixelsToIwc.applyForward(pixPointList)) self.checkNonFitsWcs(modifiedWcs)
def _preparePlugin(self, addCoaddInputs): """Prepare a `SingleFrameInputCountPlugin` for running. Sets up the plugin to run on an empty catalog together with a synthetic, content-free `~lsst.afw.image.ExposureF`. Parameters ---------- addCoaddInputs : `bool` Should we add the coadd inputs? Returns ------- inputCount : `SingleFrameInputCountPlugin` Initialized measurement plugin. catalog : `lsst.afw.table.SourceCatalog` Empty Catalog. exp : `lsst.afw.image.ExposureF` Synthetic exposure. """ exp = afwImage.ExposureF(20, 20) scale = 1.0e-5*lsst.geom.degrees wcs = afwGeom.makeSkyWcs(crpix=lsst.geom.Point2D(0, 0), crval=lsst.geom.SpherePoint(0.0, 0.0, lsst.geom.degrees), cdMatrix=afwGeom.makeCdMatrix(scale=scale)) exp.setWcs(wcs) if addCoaddInputs: exp.getInfo().setCoaddInputs(afwImage.CoaddInputs(afwTable.ExposureTable.makeMinimalSchema(), afwTable.ExposureTable.makeMinimalSchema())) ccds = exp.getInfo().getCoaddInputs().ccds record = ccds.addNew() record.setWcs(wcs) record.setBBox(exp.getBBox()) record.setValidPolygon(afwGeom.Polygon(lsst.geom.Box2D(exp.getBBox()))) schema = afwTable.SourceTable.makeMinimalSchema() measBase.SingleFramePeakCentroidPlugin(measBase.SingleFramePeakCentroidConfig(), "centroid", schema, None) schema.getAliasMap().set("slot_Centroid", "centroid") inputCount = measBase.SingleFrameInputCountPlugin(measBase.InputCountConfig(), "inputCount", schema, None) catalog = afwTable.SourceCatalog(schema) return inputCount, catalog, exp
def makeLsstExposure(galData, psfData, pixScale, variance): """ make an LSST exposure object Parameters: galData (ndarray): array of galaxy image psfData (ndarray): array of PSF image pixScale (float): pixel scale variance (float): noise variance Returns: exposure: LSST exposure object """ if not with_lsst: raise ImportError('Do not have lsstpipe!') ny, nx = galData.shape exposure = afwImg.ExposureF(nx, ny) exposure.getMaskedImage().getImage().getArray()[:, :] = galData exposure.getMaskedImage().getVariance().getArray()[:, :] = variance #Set the PSF ngridPsf = psfData.shape[0] psfLsst = afwImg.ImageF(ngridPsf, ngridPsf) psfLsst.getArray()[:, :] = psfData psfLsst = psfLsst.convertD() kernel = afwMath.FixedKernel(psfLsst) kernelPSF = meaAlg.KernelPsf(kernel) exposure.setPsf(kernelPSF) #prepare the wcs #Rotation cdelt = (pixScale * afwGeom.arcseconds) CD = afwGeom.makeCdMatrix(cdelt, afwGeom.Angle(0.)) #no rotation #wcs crval = afwGeom.SpherePoint(afwGeom.Angle(0., afwGeom.degrees), afwGeom.Angle(0., afwGeom.degrees)) #crval = afwCoord.IcrsCoord(0.*afwGeom.degrees, 0.*afwGeom.degrees) # hscpipe6 crpix = afwGeom.Point2D(0.0, 0.0) dataWcs = afwGeom.makeSkyWcs(crpix, crval, CD) exposure.setWcs(dataWcs) #prepare the frc dataCalib = afwImg.makePhotoCalibFromCalibZeroPoint(63095734448.0194) exposure.setPhotoCalib(dataCalib) return exposure
def makeMetadata(self): """Return a WCS that is typical for an image It will contain 14 cards that describe a WCS, added by makeSimpleWcsMetadata, plus 25 additional cards, including a set for WCS "A", which is what LSST uses to store xy0, and LTV1 and LTV2, which LSST used to use for xy0 """ # arbitrary values orientation = 0 * degrees flipX = False metadata = makeSimpleWcsMetadata( crpix=self.crpix, crval=self.crval, cdMatrix=makeCdMatrix(scale=self.scale, orientation=orientation, flipX=flipX), ) self.assertEqual(metadata.nameCount(), 12) # 2 CD terms are zero and so are omitted metadata.add("SIMPLE", True) metadata.add("BITPIX", 16) metadata.add("NAXIS", 2) metadata.add("NAXIS1", 500) metadata.add("NAXIS2", 200) metadata.add("BZERO", 32768) metadata.add("BSCALE", 1) metadata.add("TIMESYS", "UTC") metadata.add("UTC-OBS", "12:04:45.73") metadata.add("DATE-OBS", "2006-05-20") metadata.add("EXPTIME", 5.0) metadata.add("COMMENT", "a comment") metadata.add("COMMENT", "another comment") metadata.add("HISTORY", "some history") metadata.add("EXTEND", True) metadata.add("INHERIT", False) metadata.add("CRPIX1A", 1.0) metadata.add("CRPIX2A", 1.0) metadata.add("CRVAL1A", 300) metadata.add("CRVAL2A", 400) metadata.add("CUNIT1A", "pixels") metadata.add("CUNIT2A", "pixels") metadata.add("LTV1", -300) metadata.add("LTV2", -400) metadata.add("ZOTHER", "non-standard") return metadata
def testWarpIntoSelf(self, interpLength=10): """Cannot warp in-place """ wcs = afwGeom.makeSkyWcs( crpix=lsst.geom.Point2D(0, 0), crval=lsst.geom.SpherePoint(359, 0, lsst.geom.degrees), cdMatrix=afwGeom.makeCdMatrix(1.0e-8*lsst.geom.degrees), ) exposure = afwImage.ExposureF(lsst.geom.Extent2I(100, 100), wcs) maskedImage = exposure.getMaskedImage() warpingControl = afwMath.WarpingControl( "bilinear", "", 0, interpLength) with self.assertRaises(pexExcept.InvalidParameterError): afwMath.warpExposure(exposure, exposure, warpingControl) with self.assertRaises(pexExcept.InvalidParameterError): afwMath.warpImage(maskedImage, wcs, maskedImage, wcs, warpingControl) with self.assertRaises(pexExcept.InvalidParameterError): afwMath.warpImage(maskedImage.getImage(), wcs, maskedImage.getImage(), wcs, warpingControl)
def createPatch( tractId=1, patchId=(2, 3), # Tract and patch identifier, for dataId dims=DIMS, # Patch dimensions (Extent2I) xy0=geom.Point2I(1234, 5678), # Patch xy0 (Point2I) center=CENTER, # ICRS sky position of center (lsst.afw.geom.SpherePoint) scale=SCALE # Pixel scale (Angle) ): crpix = geom.Point2D(xy0) + geom.Extent2D(dims) * 0.5 cdMatrix = afwGeom.makeCdMatrix(scale=scale) wcs = afwGeom.makeSkyWcs(crpix=crpix, crval=center, cdMatrix=cdMatrix) patch = DummyPatch(xy0, dims) tract = DummyTract(patchId, patch, wcs) skymap = DummySkyMap(tractId, tract) dataRef = DummyDataRef( { 'tract': tractId, 'patch': ",".join(map(str, patchId)) }, deepCoadd_skyMap=skymap) return dataRef
def testWarpIntoSelf(self, interpLength=10): """Cannot warp in-place """ wcs = afwGeom.makeSkyWcs( crpix=afwGeom.Point2D(0, 0), crval=afwGeom.SpherePoint(359, 0, afwGeom.degrees), cdMatrix=afwGeom.makeCdMatrix(1.0e-8*afwGeom.degrees), ) exposure = afwImage.ExposureF(afwGeom.Extent2I(100, 100), wcs) maskedImage = exposure.getMaskedImage() warpingControl = afwMath.WarpingControl( "bilinear", "", 0, interpLength) with self.assertRaises(pexExcept.InvalidParameterError): afwMath.warpExposure(exposure, exposure, warpingControl) with self.assertRaises(pexExcept.InvalidParameterError): afwMath.warpImage(maskedImage, wcs, maskedImage, wcs, warpingControl) with self.assertRaises(pexExcept.InvalidParameterError): afwMath.warpImage(maskedImage.getImage(), wcs, maskedImage.getImage(), wcs, warpingControl)
def setUp(self): refCatDir = os.path.join(os.path.dirname(__file__), "data", "sdssrefcat") self.bbox = lsst.geom.Box2I(lsst.geom.Point2I(0, 0), lsst.geom.Extent2I(3001, 3001)) crpix = lsst.geom.Box2D(self.bbox).getCenter() self.tanWcs = afwGeom.makeSkyWcs( crpix=crpix, crval=lsst.geom.SpherePoint(215.5, 53.0, lsst.geom.degrees), cdMatrix=afwGeom.makeCdMatrix(scale=5.1e-5 * lsst.geom.degrees)) self.exposure = afwImage.ExposureF(self.bbox) self.exposure.setWcs(self.tanWcs) self.exposure.setFilter( afwImage.FilterLabel(band="r", physical="rTest")) filenames = sorted( glob.glob( os.path.join(refCatDir, 'ref_cats', 'cal_ref_cat', '??????.fits'))) self.refObjLoader = MockReferenceObjectLoaderFromFiles(filenames, htmLevel=8)
def setUp(self): crval = lsst.geom.SpherePoint(44, 45, lsst.geom.degrees) crpix = lsst.geom.PointD(0, 0) scale = 1 * lsst.geom.arcseconds self.tanWcs = afwGeom.makeSkyWcs(crpix=crpix, crval=crval, cdMatrix=afwGeom.makeCdMatrix(scale=scale)) S = 300 N = 5 if self.MatchClass == afwTable.ReferenceMatch: refSchema = LoadReferenceObjectsTask.makeMinimalSchema( filterNameList=["r"], addIsPhotometric=True) self.refCat = afwTable.SimpleCatalog(refSchema) elif self.MatchClass == afwTable.SourceMatch: refSchema = afwTable.SourceTable.makeMinimalSchema() self.refCat = afwTable.SourceCatalog(refSchema) else: raise RuntimeError("Unsupported MatchClass=%r" % (self.MatchClass,)) srcSchema = afwTable.SourceTable.makeMinimalSchema() SingleFrameMeasurementTask(schema=srcSchema) self.refCoordKey = afwTable.CoordKey(refSchema["coord"]) self.srcCoordKey = afwTable.CoordKey(srcSchema["coord"]) self.srcCentroidKey = afwTable.Point2DKey(srcSchema["slot_Centroid"]) self.sourceCat = afwTable.SourceCatalog(srcSchema) self.origSourceCat = afwTable.SourceCatalog(srcSchema) # undistorted copy self.matches = [] for i in np.linspace(0., S, N): for j in np.linspace(0., S, N): src = self.sourceCat.addNew() refObj = self.refCat.addNew() src.set(self.srcCentroidKey, lsst.geom.Point2D(i, j)) c = self.tanWcs.pixelToSky(lsst.geom.Point2D(i, j)) refObj.setCoord(c) self.matches.append(self.MatchClass(refObj, src, 0.0))
def makeDummyWcs(self, rotAngle, pixelScale, crval, flipX=True): """Make a World Coordinate System object for testing. Parameters ---------- rotAngle : `lsst.geom.Angle` rotation of the CD matrix, East from North pixelScale : `lsst.geom.Angle` Pixel scale of the projection. crval : `lsst.afw.geom.SpherePoint` Coordinates of the reference pixel of the wcs. flipX : `bool`, optional Flip the direction of increasing Right Ascension. Returns ------- `lsst.afw.geom.skyWcs.SkyWcs` A wcs that matches the inputs. """ crpix = afwGeom.Box2D(self.bbox).getCenter() cdMatrix = afwGeom.makeCdMatrix(scale=pixelScale, orientation=rotAngle, flipX=flipX) wcs = afwGeom.makeSkyWcs(crpix=crpix, crval=crval, cdMatrix=cdMatrix) return wcs
def setUp(self): # define the position and size of one CCD in the focal plane self.pixelSizeMm = 0.024 # mm/pixel self.ccdOrientation = 5*lsst.geom.degrees # orientation of pixel w.r.t. focal plane self.plateScale = 0.15*lsst.geom.arcseconds # angle/pixel self.bbox = lsst.geom.Box2I(lsst.geom.Point2I(0, 0), lsst.geom.Extent2I(2000, 4000)) self.crpix = lsst.geom.Point2D(1000, 2000) self.crval = lsst.geom.SpherePoint(10, 40, lsst.geom.degrees) self.orientation = -45*lsst.geom.degrees self.scale = 1.0*lsst.geom.arcseconds # position of 0,0 pixel position in focal plane self.ccdPositionMm = lsst.geom.Point2D(25.0, 10.0) self.pixelToFocalPlane = self.makeAffineTransform( offset=lsst.geom.Extent2D(self.ccdPositionMm), rotation=self.ccdOrientation, scale=self.pixelSizeMm, ) cdMatrix = afwGeom.makeCdMatrix(scale=self.scale, orientation=self.orientation) self.tanWcs = afwGeom.makeSkyWcs(crpix=self.crpix, crval=self.crval, cdMatrix=cdMatrix) self.radPerMm = self.plateScale.asRadians()/self.pixelSizeMm # at center of field bboxD = lsst.geom.Box2D(self.bbox) self.pixelPoints = bboxD.getCorners() self.pixelPoints.append(bboxD.getCenter())