def drawCoaddInputs(exposure, frame=None, ctype=None, bin=1, display="deferToFrame"): """Draw the bounding boxes of input exposures to a coadd on a display frame with the specified ctype, assuming display.mtv() has already been called on the given exposure on this frame. All coordinates are divided by bin, as is right and proper for overlaying on a binned image """ coaddWcs = exposure.getWcs() catalog = exposure.getInfo().getCoaddInputs().ccds offset = afwGeom.PointD() - afwGeom.PointD(exposure.getXY0()) display = _getDisplayFromDisplayOrFrame(display, frame) with display.Buffering(): for record in catalog: ccdBox = afwGeom.Box2D(record.getBBox()) ccdCorners = ccdBox.getCorners() coaddCorners = [ coaddWcs.skyToPixel(record.getWcs().pixelToSky(point)) + offset for point in ccdCorners ] display.line( [(coaddCorners[i].getX() / bin, coaddCorners[i].getY() / bin) for i in range(-1, 4)], ctype=ctype)
def testFractionalPixel(self): """Check that we can create a CoaddPsf with 10 elements.""" print("FractionalPixelTest") cd21 = 5.55555555e-05 cd12 = 5.55555555e-05 cd11 = 0.0 cd22 = 0.0 wcs = afwImage.makeWcs(self.crval, self.crpix, cd11, cd12, cd21, cd22) # make a single record with an oblong Psf record = self.mycatalog.getTable().makeRecord() psf = makeBiaxialGaussianPsf(100, 100, 6.0, 6.0, 0.0) record.setPsf(psf) record.setWcs(wcs) record['weight'] = 1.0 record['id'] = 1 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) psf.computeImage(afwGeom.PointD(0.25, 0.75)) psf.computeImage(afwGeom.PointD(0.25, 0.75)) psf.computeImage(afwGeom.PointD(1000, 1000)) m0, xbar, ybar, mxx, myy, x0, y0 = getPsfMoments( psf, afwGeom.Point2D(0.25, 0.75)) cm0, cxbar, cybar, cmxx, cmyy, cx0, cy0 = getPsfMoments( mypsf, afwGeom.Point2D(0.25, 0.75)) self.assertAlmostEqual(x0 + xbar, cx0 + cxbar, delta=0.01) self.assertAlmostEqual(y0 + ybar, cy0 + cybar, delta=0.01)
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 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 focalMmToCcdPixel(self, focalPlaneX, focalPlaneY): r"""Given focal plane position return the detector position Parameters ---------- focalPlaneX : `float` The x-focal plane position (mm) relative to the centre of the camera focalPlaneY : `float` The y-focal plane position (mm) relative to the centre of the camera N.b. all pixel coordinates have the centre of the bottom-left pixel at (0.0, 0.0) and CCD columns are taken to be vertical, with "R00" in the bottom left of the image Returns ------- detectorName : `str` The name of the detector ccdX : `int` The column pixel position relative to the corner of the detector ccdY : `int` The row pixel position relative to the corner of the detector Raises ------ RuntimeError If the requested position doesn't lie on a detector """ detector, ccdXY = focalMmToCcdPixel( self.camera, afwGeom.PointD(focalPlaneX, focalPlaneY)) ccdX, ccdY = ccdXY return detector.getName(), ccdX, ccdY
def setUp(self): # Construct an arbitrary WCS for testing. crval = afwGeom.SpherePoint(45.0, 45.0, afwGeom.degrees) scale = 0.2*afwGeom.arcseconds crpix = afwGeom.PointD(100, 100) self.wcs = afwGeom.makeSkyWcs(crpix=crpix, crval=crval, cdMatrix=afwGeom.makeCdMatrix(scale=scale))
def correction(dimensions, wcs): image = afwImage.ImageF(dimensions) for y in xrange(image.getHeight()): for x in xrange(image.getWidth()): area = wcs.pixArea(afwGeom.PointD(x, y)) image.set(x, y, 1.0 / area) return image
def showPsf(psf, eigenValues=None, XY=None, normalize=True, frame=None): """Display a PSF's eigen images If normalize is True, set the largest absolute value of each eigenimage to 1.0 (n.b. sum == 0.0 for i > 0) """ if eigenValues: coeffs = eigenValues elif XY is not None: coeffs = psf.getLocalKernel(afwGeom.PointD(XY[0], XY[1])).getKernelParameters() else: coeffs = None mos = displayUtils.Mosaic(gutter=2, background=-0.1) for i, k in enumerate(psf.getKernel().getKernelList()): im = afwImage.ImageD(k.getDimensions()) k.computeImage(im, False) if normalize: im /= numpy.max(numpy.abs(im.getArray())) if coeffs: mos.append(im, "%g" % (coeffs[i]/coeffs[0])) else: mos.append(im) mos.makeMosaic(frame=frame, title="Kernel Basis Functions") return mos
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 = afwGeom.PointD(1000 - 10.0 * i, 1000.0 - 10.0 * i) wcs = afwImage.makeWcs(self.crval, crpix, self.cd11, self.cd12, self.cd21, self.cd22) record.setWcs(wcs) record['weight'] = 1.0 * (i + 1) record['id'] = i record.setBBox( afwGeom.Box2I(afwGeom.Point2I(0, 0), afwGeom.Extent2I(1000, 1000))) validPolygon = Polygon( afwGeom.Box2D(afwGeom.Point2D(0, 0), afwGeom.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 [ afwGeom.Point2D(50, 50), afwGeom.Point2D(500, 500), afwGeom.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 test1(self): wcsfn = os.path.join(self.datadir, 'imsim-v85518312-fu-R43-S12.wcs2') hdr = readMetadata(wcsfn) wcs1 = afwGeom.makeSkyWcs(hdr) crval = wcs1.getSkyOrigin() cd = wcs1.getCdMatrix() print(cd) crval_p = afwGeom.Point2D(crval.getLongitude().asDegrees(), crval.getLatitude().asDegrees()) origin = wcs1.getPixelOrigin() print(crval_p) print(origin) wcs2 = afwGeom.makeSkyWcs(crpix=origin, crval=crval, cdMatrix=cd) for wcs in [wcs1, wcs2]: print(wcs) print('x, y, RA, Dec, pixscale("/pix), pixscale2') for x, y in [(0, 0), (300, 0), (350, 0), (360, 0), (370, 0), (380, 0), (400, 0)]: pixPos = afwGeom.PointD(x, y) radec = wcs.pixelToSky(pixPos) ra = radec.getLongitude().asDegrees() dec = radec.getLatitude().asDegrees() pixscale = wcs.getPixelScale(pixPos).asArcseconds() print(x, y, ra, dec, pixscale) self.assertLess(abs(pixscale - 0.2), 1e-3)
def setUp(self): self.crval = afwCoord.IcrsCoord(afwGeom.PointD(44., 45.)) self.crpix = afwGeom.Point2D(15000, 4000) arcsecPerPixel = 1 / 3600.0 CD11 = arcsecPerPixel CD12 = 0 CD21 = 0 CD22 = arcsecPerPixel self.wcs = afwImage.makeWcs(self.crval, self.crpix, CD11, CD12, CD21, CD22) refSchema = afwTable.SimpleTable.makeMinimalSchema() self.refCentroidKey = afwTable.Point2DKey.addFields( refSchema, "centroid", "centroid", "pixels") self.refCoordKey = afwTable.CoordKey(refSchema["coord"]) self.refCat = afwTable.SimpleCatalog(refSchema) # an alias is required to make src.getCentroid() work; # simply defining a field named "slot_Centroid" doesn't suffice srcSchema = afwTable.SourceTable.makeMinimalSchema() self.srcCentroidKey = afwTable.Point2DKey.addFields( srcSchema, "base_SdssCentroid", "centroid", "pixels") srcAliases = srcSchema.getAliasMap() srcAliases.set("slot_Centroid", "base_SdssCentroid") self.srcCoordKey = afwTable.CoordKey(srcSchema["coord"]) self.sourceCat = afwTable.SourceCatalog(srcSchema)
def testCoordAliases(self): with self.assertWarns(FutureWarning): self.assertIsInstance(afwGeom.ExtentI(), lsst.geom.ExtentI) with self.assertWarns(FutureWarning): self.assertIsInstance(afwGeom.Extent2I(), lsst.geom.Extent2I) with self.assertWarns(FutureWarning): self.assertIsInstance(afwGeom.Extent3I(), lsst.geom.Extent3I) with self.assertWarns(FutureWarning): self.assertIsInstance(afwGeom.ExtentD(), lsst.geom.ExtentD) with self.assertWarns(FutureWarning): self.assertIsInstance(afwGeom.Extent2D(), lsst.geom.Extent2D) with self.assertWarns(FutureWarning): self.assertIsInstance(afwGeom.Extent3D(), lsst.geom.Extent3D) with self.assertWarns(FutureWarning): self.assertIsInstance(afwGeom.PointI(), lsst.geom.PointI) with self.assertWarns(FutureWarning): self.assertIsInstance(afwGeom.Point2I(), lsst.geom.Point2I) with self.assertWarns(FutureWarning): self.assertIsInstance(afwGeom.Point3I(), lsst.geom.Point3I) with self.assertWarns(FutureWarning): self.assertIsInstance(afwGeom.PointD(), lsst.geom.PointD) with self.assertWarns(FutureWarning): self.assertIsInstance(afwGeom.Point2D(), lsst.geom.Point2D) with self.assertWarns(FutureWarning): self.assertIsInstance(afwGeom.Point3D(), lsst.geom.Point3D)
def ccdPixelToAmpPixel(self, ccdX, ccdY, detectorName=None): r"""Given position within a detector, return the amplifier position Parameters ---------- ccdX : `int` column pixel position within detector ccdY : `int` row pixel position within detector detectorName : `str` Name of detector (or default from setDetectorName() if None) N.b. all pixel coordinates have the centre of the bottom-left pixel at (0.0, 0.0) Returns ------- channel: `int` Channel number of amplifier (1-indexed; identical to HDU) ampX : `int` The column coordinate relative to the corner of the single-amp image ampY : `int` The row coordinate relative to the corner of the single-amp image Raises ------ RuntimeError If the requested pixel doesn't lie on the detector """ amp, ampXY = ccdPixelToAmpPixel(afwGeom.PointD(ccdX, ccdY), self.getDetector(detectorName)) ampX, ampY = ampXY return ampToChannel(amp), ampX, ampY
def makeFocalPlaneWcs(pixelSize, referencePixel): """Make a WCS for the focal plane geometry (i.e. one that returns positions in "mm") Parameters ---------- pixelSize : `float` Size of the image pixels in physical units referencePixel : `lsst.afw.geom.Point2D` Pixel for origin of WCS Returns ------- `lsst.afw.geom.Wcs` Wcs object for mapping between pixels and focal plane. """ md = dafBase.PropertySet() if referencePixel is None: referencePixel = afwGeom.PointD(0, 0) for i in range(2): md.set("CRPIX%d"%(i+1), referencePixel[i]) md.set("CRVAL%d"%(i+1), 0.) md.set("CDELT1", pixelSize[0]) md.set("CDELT2", pixelSize[1]) md.set("CTYPE1", "CAMERA_X") md.set("CTYPE2", "CAMERA_Y") md.set("CUNIT1", "mm") md.set("CUNIT2", "mm") return afwGeom.makeSkyWcs(md)
def setUp(self): crval = IcrsCoord(afwGeom.PointD(44., 45.)) crpix = afwGeom.PointD(0, 0) arcsecPerPixel = 1 / 3600.0 CD11 = arcsecPerPixel CD12 = 0 CD21 = 0 CD22 = arcsecPerPixel self.tanWcs = makeWcs(crval, crpix, CD11, CD12, CD21, CD22) 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 testSwap(self): x00, y00, x01, y01 = (0., 1., 2., 3.) x10, y10, x11, y11 = (4., 5., 6., 7.) box0 = geom.Box2D(geom.PointD(x00, y00), geom.PointD(x01, y01)) box1 = geom.Box2D(geom.PointD(x10, y10), geom.PointD(x11, y11)) box0.swap(box1) self.assertEqual(box0.getMinX(), x10) self.assertEqual(box0.getMinY(), y10) self.assertEqual(box0.getMaxX(), x11) self.assertEqual(box0.getMaxY(), y11) self.assertEqual(box1.getMinX(), x00) self.assertEqual(box1.getMinY(), y00) self.assertEqual(box1.getMaxX(), x01) self.assertEqual(box1.getMaxY(), y01)
def testCentroider(self): """Measure the centroid""" s = self.mySetup() # this does not match exactly, and it used to self.assertFloatsAlmostEqual(s.getCentroid(), afwGeom.PointD(self.xcen, self.ycen), rtol=.01)
def testSVAnalyticKernel(self): """Test spatially varying AnalyticKernel using a Gaussian function Just tests cloning. """ kWidth = 5 kHeight = 8 # spatial model spFunc = afwMath.PolynomialFunction2D(1) # spatial parameters are a list of entries, one per kernel parameter; # each entry is a list of spatial parameters sParams = ( (1.0, 1.0, 0.0), (1.0, 0.0, 1.0), (0.5, 0.5, 0.5), ) gaussFunc = afwMath.GaussianFunction2D(1.0, 1.0, 0.0) kernel = afwMath.AnalyticKernel(kWidth, kHeight, gaussFunc, spFunc) kernel.setSpatialParameters(sParams) kernelClone = kernel.clone() errStr = self.compareKernels(kernel, kernelClone) if errStr: self.fail(errStr) newSParams = ( (0.1, 0.2, 0.5), (0.1, 0.5, 0.2), (0.2, 0.3, 0.3), ) kernel.setSpatialParameters(newSParams) errStr = self.compareKernels(kernel, kernelClone) if not errStr: self.fail( "Clone was modified by changing original's spatial parameters") # # check that we can construct a FixedKernel from a LinearCombinationKernel # x, y = 100, 200 kernel2 = afwMath.FixedKernel(kernel, afwGeom.PointD(x, y)) self.assertTrue(re.search("AnalyticKernel", kernel.toString())) self.assertFalse(kernel2.isSpatiallyVarying()) self.assertTrue(re.search("FixedKernel", kernel2.toString())) self.assertTrue(kernel.isSpatiallyVarying()) kim = afwImage.ImageD(kernel.getDimensions()) kernel.computeImage(kim, True, x, y) kim2 = afwImage.ImageD(kernel2.getDimensions()) kernel2.computeImage(kim2, True) self.assertTrue(numpy.allclose(kim.getArray(), kim2.getArray()))
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 testFractionalPixel(self): """Check that we can create a CoaddPsf with 10 elements""" print "FractionalPixelTest" # 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) cd21 = 5.55555555e-05 cd12 = 5.55555555e-05 cd11 = 0.0 cd22 = 0.0 wcs = afwImage.makeWcs(crval, crpix, cd11, cd12, cd21, cd22) schema = afwTable.ExposureTable.makeMinimalSchema() schema.addField("weight", type="D", doc="Coadd weight") mycatalog = afwTable.ExposureCatalog(schema) # make a single record with an oblong Psf record = mycatalog.getTable().makeRecord() psf = makeBiaxialGaussianPsf(100, 100, 6.0, 6.0, 0.0) record.setPsf(psf) 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) img = psf.computeImage(afwGeom.PointD(0.25, 0.75)) img = psf.computeImage(afwGeom.PointD(0.25, 0.75)) img = psf.computeImage(afwGeom.PointD(1000, 1000)) m0, xbar, ybar, mxx, myy, x0, y0 = getPsfMoments( psf, afwGeom.Point2D(0.25, 0.75)) cm0, cxbar, cybar, cmxx, cmyy, cx0, cy0 = getPsfMoments( mypsf, afwGeom.Point2D(0.25, 0.75)) self.assertTrue(testRelDiff(x0 + xbar, cx0 + cxbar, .01)) self.assertTrue(testRelDiff(y0 + ybar, cy0 + cybar, .01))
def plantSources(bbox, kwid, sky, coordList, addPoissonNoise=True): """Make an exposure with stars (modelled as Gaussians) @param bbox: parent bbox of exposure @param kwid: kernel width (and height; kernel is square) @param sky: amount of sky background (counts) @param coordList: a list of [x, y, counts, sigma], where: * x,y are relative to exposure origin * counts is the integrated counts for the star * sigma is the Gaussian sigma in pixels @param addPoissonNoise: add Poisson noise to the exposure? """ # make an image with sources img = afwImage.ImageD(bbox) meanSigma = 0.0 for coord in coordList: x, y, counts, sigma = coord meanSigma += sigma # make a single gaussian psf psf = SingleGaussianPsf(kwid, kwid, sigma) # make an image of it and scale to the desired number of counts thisPsfImg = psf.computeImage(afwGeom.PointD(x, y)) thisPsfImg *= counts # bbox a window in our image and add the fake star image psfBox = thisPsfImg.getBBox() psfBox.clip(bbox) if psfBox != thisPsfImg.getBBox(): thisPsfImg = thisPsfImg[psfBox, afwImage.PARENT] imgSeg = img[psfBox, afwImage.PARENT] imgSeg += thisPsfImg meanSigma /= len(coordList) img += sky # add Poisson noise if (addPoissonNoise): np.random.seed(seed=1) # make results reproducible imgArr = img.getArray() imgArr[:] = np.random.poisson(imgArr) # bundle into a maskedimage and an exposure mask = afwImage.Mask(bbox) var = img.convertFloat() img -= sky mimg = afwImage.MaskedImageF(img.convertFloat(), mask, var) exposure = afwImage.makeExposure(mimg) # insert an approximate psf psf = SingleGaussianPsf(kwid, kwid, meanSigma) exposure.setPsf(psf) return exposure
def makeitLsst(prefs, context, saveWcs=False, plot=dict()): """This is the python wrapper that reads lsst tables """ # Create an array of PSFs (one PSF for each extension) if prefs.getVerboseType() != prefs.QUIET: print("----- %d input catalogues:" % prefs.getNcat()) if saveWcs: # only needed for making plots wcssList = [] fields = psfexLib.vectorField() for cat in prefs.getCatalogs(): field = psfexLib.Field(cat) wcss = [] wcssList.append(wcss) with fits.open(cat): # Hack: I want the WCS so I'll guess where the calexp is to be found calexpFile = guessCalexp(cat) md = readMetadata(calexpFile) wcs = afwGeom.makeSkyWcs(md) if not wcs: cdMatrix = np.array([1.0, 0.0, 0.0, 1.0]) cdMatrix.shape = (2, 2) wcs = afwGeom.makeSkyWcs(crpix=afwGeom.PointD(0, 0), crval=afwGeom.SpherePoint( 0.0, 0.0, afwGeom.degrees), cdMatrix=cdMatrix) naxis1, naxis2 = md.getScalar("NAXIS1"), md.getScalar("NAXIS2") # Find how many rows there are in the catalogue md = readMetadata(cat) field.addExt(wcs, naxis1, naxis2, md.getScalar("NAXIS2")) if saveWcs: wcss.append((wcs, naxis1, naxis2)) field.finalize() fields.append(field) fields[0].getNext() # number of extensions prefs.getPsfStep() sets = psfexLib.vectorSet() for set in load_samplesLsst(prefs, context, plot=plot): sets.append(set) psfexLib.makeit(fields, sets) ret = [[f.getPsfs() for f in fields], sets] if saveWcs: ret.append(wcssList) return ret
def setUp(self): crval = afwCoord.IcrsCoord(afwGeom.PointD(44., 45.)) crpix = afwGeom.Point2D(15000, 4000) arcsecPerPixel = 1 / 3600.0 CD11 = arcsecPerPixel CD12 = 0 CD21 = 0 CD22 = arcsecPerPixel self.tanWcs = afwImage.makeWcs(crval, crpix, CD11, CD12, CD21, CD22) self.loadData()
def acsEventCallback(key, source, im, frame): """Callback for event handlers to find COSMOS ACS cutout. \param key Key struck \param source The Source under the cursor \param im The (HSC) image cutout displayed in frame \param frame The frame that the HSC data's displayed in (we'll use the next one) We also use the following static members of utils.EventHandler (if set): sizeCutout The size of the HSC cutout (arcsec; default: 4.0) scale Make the COSMOS image with pixel size scale*HSC's pixel size (default 0.25 => 0.42mas) Use as e.g. utils.eventCallbacks['c'] = cosmos.acsEventCallback """ sizeCutout = utils.EventHandler.sizeCutout if hasattr( utils.EventHandler, "sizeCutout") else 4.0 # arcsec scale = utils.EventHandler.scale if hasattr( utils.EventHandler, "scale") else 0.25 # Pixel size scaling pos = source.get("coord") exp = getCosmosCutout(*pos.getPosition(), sizeX=sizeCutout) if im and exp and exp.getWcs(): # # Resample and rotate to the HSC orientation # warpingControl = afwMath.WarpingControl("lanczos3") rat = im.getWcs().pixelScale().asArcseconds() / exp.getWcs( ).pixelScale().asArcseconds() hsize = int(0.5 * exp.getWidth() / (scale * rat)) rexp = afwImage.ExposureF(2 * hsize + 1, 2 * hsize + 1) rexp.setWcs( afwImage.Wcs(pos.getPosition(), afwGeom.Point2D(hsize, hsize), im.getWcs().getCDMatrix() * scale)) afwMath.warpExposure(rexp, exp, warpingControl) else: print "\nI'm unable to remap the cosmos image to your coordinates, sorry" rexp = exp.getMaskedImage().getImage() frame += 1 rim = rexp if hasattr(rim, "getMaskedImage"): rim = rim.getMaskedImage().getImage() if hasattr(rim, "getImage"): rim = rim.getImage() disp = afwDisplay.Display(frame=frame) disp.mtv(rim) if hasattr(rexp, "getWcs"): cen = rexp.getWcs().skyToPixel(pos) - afwGeom.PointD(rexp.getXY0()) disp.pan(*cen) disp.dot('+', *cen)
def testCreate(self): """Check that we can create a CoaddPsf with 9 elements.""" print("CreatePsfTest") # 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 = afwGeom.makeSkyWcs(crpix=crpix, crval=self.crval, cdMatrix=self.cdMatrix) 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, self.wcsref, 'customweightname') # check to be sure that we got the right number of components, in the right order self.assertEqual(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.assertEqual(i, id) self.assertEqual(weight, 1.0 * (i + 1)) self.assertEqual(bbox.getBeginX(), 0) self.assertEqual(bbox.getBeginY(), 0) self.assertEqual(bbox.getEndX(), 1000 * i) self.assertEqual(bbox.getEndY(), 1000 * i) self.assertAlmostEqual(wcs.getPixelOrigin().getX(), (1000.0 * i)) self.assertAlmostEqual(wcs.getPixelOrigin().getY(), (1000.0 * i)) m0, xbar, ybar, mxx, myy, x0, y0 = getPsfMoments( psf, afwGeom.Point2D(0, 0)) self.assertAlmostEqual(i * i, mxx, delta=0.01) self.assertAlmostEqual(i * i, myy, delta=0.01)
def setUp(self): self.cd11 = 5.55555555e-05 self.cd12 = 0.0 self.cd21 = 0.0 self.cd22 = 5.55555555e-05 self.crval1 = 0.0 self.crval2 = 0.0 self.crpix = afwGeom.PointD(1000, 1000) self.crval = afwCoord.Coord(afwGeom.Point2D(self.crval1, self.crval2)) self.wcsref = afwImage.makeWcs(self.crval, self.crpix, self.cd11, self.cd12, self.cd21, self.cd22) schema = afwTable.ExposureTable.makeMinimalSchema() self.weightKey = schema.addField("weight", type="D", doc="Coadd weight") self.mycatalog = afwTable.ExposureCatalog(schema)
def testCamera(self): """Test if we can build a Camera out of Rafts""" #print >> sys.stderr, "Skipping testCamera"; return cameraInfo = {"ampSerial" : CameraGeomTestCase.ampSerial} camera = cameraGeomUtils.makeCamera(self.geomPolicy, cameraInfo=cameraInfo) if display: cameraGeomUtils.showCamera(camera, ) ds9.incrDefaultFrame() if False: print cameraGeomUtils.describeCamera(camera) self.assertEqual(camera.getAllPixels().getWidth(), cameraInfo["width"]) self.assertEqual(camera.getAllPixels().getHeight(), cameraInfo["height"]) name = "R:1,0" self.assertEqual(camera.findDetector(cameraGeom.Id(name)).getId().getName(), name) self.assertEqual(camera.getSize().getMm()[0], cameraInfo["widthMm"]) self.assertEqual(camera.getSize().getMm()[1], cameraInfo["heightMm"]) # # Test mapping pixel <--> mm # for ix, iy, x, y in [(102, 500, -3.12, 2.02), (152, 525, -2.62, 2.27), (714, 500, 3.12, 2.02), ]: pix = afwGeom.PointD(ix, iy) # wrt raft LLC pos = cameraGeom.FpPoint(x, y) # center of pixel wrt raft center posll = cameraGeom.FpPoint(x, y) # llc of pixel wrt raft center # may need to restructure this since adding FpPoint if False: self.assertEqual(camera.getPixelFromPosition(pos), pix) # there is no unique mapping from a pixel to a focal plane position # ... the pixel could be on any ccd if False: self.assertEqual(camera.getPositionFromPixel(pix).getMm(), posll.getMm()) # Check that we can find an Amp in the bowels of the camera ccdName = "C:1,0" amp = cameraGeomUtils.findAmp(camera, cameraGeom.Id(ccdName), 1, 2) self.assertFalse(amp is None) self.assertEqual(amp.getId().getName(), "ID7") self.assertEqual(amp.getParent().getId().getName(), ccdName)
def testNullDistortionDefaultCcd(self): """Test that we can use a NullDistortion even if the Detector is default-constructed""" ccd = cameraGeom.Ccd(cameraGeom.Id("dummy")) distorter = cameraGeom.NullDistortion() pin = afwGeom.PointD(0, 0) pout = distorter.undistort(pin, ccd) self.assertEqual(pin, pout) ein = geomEllip.Quadrupole(1, 0, 1) eout = distorter.distort(pin, ein, ccd) self.assertEqual(ein, eout)
def setUp(self): scale = 5.55555555e-05 * afwGeom.degrees self.cdMatrix = afwGeom.makeCdMatrix(scale=scale, flipX=True) self.crpix = afwGeom.PointD(1000, 1000) self.crval = afwGeom.SpherePoint(0.0, 0.0, afwGeom.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 maskVignetting(self, mask, detector): """Mask vignetted pixels in-place @param mask: Mask image to modify @param detector: Detector for transformation to focal plane coords """ mask.addMaskPlane(self.config.maskPlane) bitMask = mask.getPlaneBitMask(self.config.maskPlane) w, h = mask.getWidth(), mask.getHeight() numCorners = 0 # Number of corners outside radius for i, j in ((0, 0), (0, h-1), (w-1, 0), (w-1, h-1)): x,y = detector.getPositionFromPixel(afwGeom.PointD(i, j)).getMm() if math.hypot(x - self.config.vignette.xCenter, y - self.config.vignette.yCenter) > self.config.radius: numCorners += 1 if numCorners == 0: # Nothing to be masked self.log.info("Detector %s is unvignetted" % detector.getId().getSerial()) return if numCorners == 4: # Everything to be masked # We ignore the question of how we're getting any data from a CCD that's totally vignetted... self.log.warn("Detector %s is completely vignetted" % detector.getId().getSerial()) mask |= bitMask return # We have to go pixel by pixel x = np.empty((h, w)) y = np.empty_like(x) for j in range(mask.getHeight()): for i in range(mask.getWidth()): x[j, i], y[j, i] = detector.getPositionFromPixel(afwGeom.PointD(i, j)).getMm() R = np.hypot(x - self.config.vignette.xCenter, y - self.config.vignette.yCenter) isBad = R > self.config.vignette.radius self.log.info("Detector %s has %f%% pixels vignetted" % (detector.getId().getSerial(), isBad.sum()/float(isBad.size)*100.0)) maskArray = mask.getArray() xx, yy = np.meshgrid(np.arange(w), np.arange(h)) maskArray[yy[isBad], xx[isBad]] |= bitMask