def setUp(self): self.x0, self.y0 = 0, 0 self.nx, self.ny = 512, 512 #2048, 4096 self.sky = 100.0 self.nObj = 100 # make a distorter # This is a lot of distortion ... from circle r=1, to ellipse with a=1.3 (ie. 30%) # For suprimecam, we expect only about 5% self.distCoeffs = [0.0, 1.0, 2.0e-04, 3.0e-8] lanczosOrder = 3 coefficientsDistort = True self.distorter = cameraGeom.RadialPolyDistortion(self.distCoeffs, coefficientsDistort, lanczosOrder) # make a detector self.detector = cameraUtils.makeDefaultCcd(afwGeom.Box2I(afwGeom.Point2I(0,0), afwGeom.Extent2I(self.nx, self.ny))) self.detector.setDistortion(self.distorter) self.detector.setCenter(cameraGeom.FpPoint(255.5, 255.5)) # move boresight from center to 0,0 if False: for x,y in [(0,0), (0, 511), (511,0), (511, 511)]: p = afwGeom.Point2D(x, y) iqq = self.distorter.distort(p, geomEllip.Quadrupole(), self.detector) print x, y, geomEllip.Axes(iqq) print self.detector.getPositionFromPixel(p).getMm() print "Max distortion on this detector: ", self.distorter.computeMaxShear(self.detector) # detection policies self.detConfig = measAlg.SourceDetectionConfig() # Cannot use default background approximation order (6) for such a small image. self.detConfig.background.approxOrder = 4 # measurement policies self.measSrcConfig = measAlg.SourceMeasurementConfig() # psf star selector starSelectorFactory = measAlg.starSelectorRegistry["secondMoment"] starSelectorConfig = starSelectorFactory.ConfigClass() starSelectorConfig.fluxLim = 5000.0 starSelectorConfig.histSize = 32 starSelectorConfig.clumpNSigma = 1.0 starSelectorConfig.badFlags = [] self.starSelector = starSelectorFactory(starSelectorConfig) # psf determiner psfDeterminerFactory = measAlg.psfDeterminerRegistry["pca"] psfDeterminerConfig = psfDeterminerFactory.ConfigClass() width, height = self.nx, self.ny nEigenComponents = 3 psfDeterminerConfig.sizeCellX = width//3 psfDeterminerConfig.sizeCellY = height//3 psfDeterminerConfig.nEigenComponents = nEigenComponents psfDeterminerConfig.spatialOrder = 1 psfDeterminerConfig.kernelSizeMin = 31 psfDeterminerConfig.nStarPerCell = 0 psfDeterminerConfig.nStarPerCellSpatialFit = 0 # unlimited self.psfDeterminer = psfDeterminerFactory(psfDeterminerConfig)
def skyMapToCamera(self, dataIds): """Make a minimal camera based on the skymap; ONLY DESIGNED TO WORK WITH 1 TRACT (sorry, future developer)""" tracts = set(x["tract"] for x in dataIds) assert(len(tracts) == 1) self.tract = tracts.pop() cols = set([x["patch"][0] for x in dataIds]) # x rows = set([x["patch"][1] for x in dataIds]) # y col0 = min(cols) row0 = min(rows) ncols = max(cols) - col0 + 1 nrows = max(rows) - row0 + 1 origBBox = afwGeom.Box2I() raftId = cameraGeom.Id(0, str(self.tract)) raft = cameraGeom.Raft(raftId, ncols, nrows) for nId, dataId in enumerate(dataIds): patch = self.skyMap[self.tract].getPatchInfo(dataId["patch"]) detId = cameraGeom.Id(nId, "%d-%d,%d" % (self.tract, patch.getIndex()[0], patch.getIndex()[1])) bbox = patch.getInnerBBox() # outer bbox overlaps, inner doesn't origBBox.include(bbox) # capture the full extent of the skymap bbox.shift(-afwGeom.Extent2I(bbox.getBegin())) # need the bbox to be w.r.t. the raft coord system; i.e. 0 ccd = cameraGeomUtils.makeDefaultCcd(bbox, detId=detId) col = patch.getIndex()[0] - col0 row = patch.getIndex()[1] - row0 xc = bbox.getBeginX() + 0.5 * bbox.getWidth() yc = bbox.getBeginY() + 0.5 * bbox.getHeight() raft.addDetector(afwGeom.Point2I(col, row), cameraGeom.FpPoint(afwGeom.Point2D(xc, yc)), cameraGeom.Orientation(), ccd) raftBbox = raft.getAllPixels() xc = origBBox.getBeginX() + 0.5 * origBBox.getWidth() yc = origBBox.getBeginY() + 0.5 * origBBox.getHeight() cameraId = cameraGeom.Id(0, "Skymap") camera = cameraGeom.Camera(cameraId, 1, 1) camera.addDetector(afwGeom.Point2I(0, 0), cameraGeom.FpPoint(afwGeom.Point2D(xc, yc)), cameraGeom.Orientation(), raft) self.camera = camera # Now, redo the assignments in __init__ for r in self.camera: raft = cameraGeom.cast_Raft(r) raftName = raft.getId().getName().strip() self.detectors[raftName] = raft self.rafts[raftName] = raft for c in raft: ccd = cameraGeom.cast_Ccd(c) ccdName = ccd.getId().getName().strip() self.detectors[ccdName] = ccd self.sensors[ccdName] = ccd self.nSensor += 1 self.raftCcdKeys.append([raftName, ccdName])
def setUp(self): self.prynt = False nx, ny = 6001, 8001 pixelSize = 1.0 # mm allPixels = afwGeom.BoxI(afwGeom.PointI(0, 0), afwGeom.ExtentI(nx, ny)) self.det = cameraGeomUtils.makeDefaultCcd(allPixels, pixelSize=pixelSize) self.det.setCenter(cameraGeom.FpPoint(int(0.5*nx), int(0.5*ny))) # try the suprimecam numbers self.coeffs = [0.0, 1.0, 7.16417e-08, 3.03146e-10, 5.69338e-14, -6.61572e-18] self.xs = [0.0, 1000.0, 5000.0] self.ys = [0.0, 1000.0, 4000.0]
def setUp(self): self.prynt = False nx, ny = 6001, 8001 pixelSize = 1.0 # mm allPixels = afwGeom.BoxI(afwGeom.PointI(0, 0), afwGeom.ExtentI(nx, ny)) self.det = cameraGeomUtils.makeDefaultCcd(allPixels, pixelSize=pixelSize) self.det.setCenter(cameraGeom.FpPoint(int(0.5 * nx), int(0.5 * ny))) # try the suprimecam numbers self.coeffs = [ 0.0, 1.0, 7.16417e-08, 3.03146e-10, 5.69338e-14, -6.61572e-18 ] self.xs = [0.0, 1000.0, 5000.0] self.ys = [0.0, 1000.0, 4000.0]
def setUp(self): self.x0, self.y0 = 0, 0 self.nx, self.ny = 512, 512 #2048, 4096 self.sky = 100.0 self.nObj = 100 # make a distorter # This is a lot of distortion ... from circle r=1, to ellipse with a=1.3 (ie. 30%) # For suprimecam, we expect only about 5% self.distCoeffs = [0.0, 1.0, 2.0e-04, 3.0e-8] lanczosOrder = 3 coefficientsDistort = True self.distorter = cameraGeom.RadialPolyDistortion( self.distCoeffs, coefficientsDistort, lanczosOrder) # make a detector self.detector = cameraUtils.makeDefaultCcd( afwGeom.Box2I(afwGeom.Point2I(0, 0), afwGeom.Extent2I(self.nx, self.ny))) self.detector.setDistortion(self.distorter) self.detector.setCenter(cameraGeom.FpPoint( 255.5, 255.5)) # move boresight from center to 0,0 if False: for x, y in [(0, 0), (0, 511), (511, 0), (511, 511)]: p = afwGeom.Point2D(x, y) iqq = self.distorter.distort(p, geomEllip.Quadrupole(), self.detector) print x, y, geomEllip.Axes(iqq) print self.detector.getPositionFromPixel(p).getMm() print "Max distortion on this detector: ", self.distorter.computeMaxShear( self.detector) # detection policies self.detConfig = measAlg.SourceDetectionConfig() # measurement policies self.measSrcConfig = measAlg.SourceMeasurementConfig() # psf star selector starSelectorFactory = measAlg.starSelectorRegistry["secondMoment"] starSelectorConfig = starSelectorFactory.ConfigClass() starSelectorConfig.fluxLim = 5000.0 starSelectorConfig.histSize = 32 starSelectorConfig.clumpNSigma = 1.0 starSelectorConfig.badFlags = [] self.starSelector = starSelectorFactory(starSelectorConfig) # psf determiner psfDeterminerFactory = measAlg.psfDeterminerRegistry["pca"] psfDeterminerConfig = psfDeterminerFactory.ConfigClass() width, height = self.nx, self.ny nEigenComponents = 3 psfDeterminerConfig.sizeCellX = width // 3 psfDeterminerConfig.sizeCellY = height // 3 psfDeterminerConfig.nEigenComponents = nEigenComponents psfDeterminerConfig.spatialOrder = 1 psfDeterminerConfig.kernelSizeMin = 31 psfDeterminerConfig.nStarPerCell = 0 psfDeterminerConfig.nStarPerCellSpatialFit = 0 # unlimited self.psfDeterminer = psfDeterminerFactory(psfDeterminerConfig)
def testPsfDistortion(self): #distorter = cameraGeom.NullDistortion() #self.sCamDistorter #Exag distorter = self.sCamDistorter # set the psf kwid = 55 psfSigma = 4.5 psf = afwDet.createPsf("DoubleGaussian", kwid, kwid, psfSigma, psfSigma, 0.0) # create a detector which is offset from the boresight pixelSize = 0.01 # mm allPixels = afwGeom.BoxI(afwGeom.PointI(0, 0), afwGeom.ExtentI(self.nx, self.ny)) detector = cameraUtils.makeDefaultCcd(allPixels, pixelSize=pixelSize) detector.setCenterPixel(afwGeom.Point2D(self.nx/2, self.ny/2)) # try the upper right corner of chip 0 on suprimecam cenPixX, cenPixY = 5000.0, 4000.0 detector.setCenter(cameraGeom.FpPoint(cenPixX*pixelSize, cenPixY*pixelSize)) detector.setDistortion(distorter) psf.setDetector(detector) settings = {'scale': 'minmax', 'zoom':"to fit", 'mask':'transparency 80'} # use a point in the middle of the test image x = self.nx//2 y = self.ny//2 p = afwGeom.Point2D(x,y) # this is our **measured** coordinate pOrig = distorter.undistort(p, detector) # this is where p would be without optical distortion ######################################################## # check that the camera behaves as expected pos = detector.getPositionFromPixel(p) pix = detector.getPixelFromPosition(pos) print "posmm, pospix, pix", pos.getMm(), pos.getPixels(detector.getPixelSize()), pix posPix = pos.getPixels(detector.getPixelSize()) # note that p is in the center of the ccd self.assertEqual(posPix.getX(), cenPixX) self.assertEqual(posPix.getY(), cenPixY) self.assertEqual(pix.getX(), x) self.assertEqual(pix.getY(), y) ######################################################## # compare the measured shear in a psf image to the expected value # get the expected shear at p q = distorter.distort(pOrig, geomEllip.Quadrupole(), detector) ax = geomEllip.Axes(q) aKnown = ax.getA() bKnown = ax.getB() thetaKnown = ax.getTheta()*180.0/math.pi print "Shear at p: ", ax, thetaKnown # make a plain PSF doDistort = False # the default is True psfImg = psf.computeImage(p, True, doDistort) # compute a PSF at p psfImgDistInternally = psf.computeImage(p) # make a plain one and distort it ourselves # --> note that we use the undistorted pOrig ... that's where p was before the optics #psfImgOrig = psf.computeImage(pOrig, True, doDistort) #psfImgDistByUs = distorter.distort(pOrig, psfImgOrig, detector, 0.0) #shift = p - afwGeom.Extent2D(pOrig) #afwMath.offsetImage(psfImgDistByUs, shift.getX(), shift.getY(), "lanczos5", 5) psfImgDistByUs = distorter.distort(p, psfImg, detector, 0.0) # to display, we'll trim off the edge of the original so it's the same size as the distorted. wid2 = psfImgDistInternally.getWidth() edge = (psfImg.getWidth() - wid2)/2 box = afwGeom.Box2I(afwGeom.Point2I(edge, edge), afwGeom.Extent2I(wid2,wid2)) if display: ds9.mtv(afwImage.ImageD(psfImg, box), frame=1, title="psf", settings=settings) ds9.mtv(psfImgDistInternally, frame=2, title="psfDist", settings=settings) ds9.mtv(afwImage.ImageD(psfImgDistByUs, box), frame=3, title="psfDist2", settings=settings) # first make sure we can plant a known quantity and measure it # quickAndDirtyShape() must be tested to be used itself as a tester sigma = 1.0 img = plantEllipse(kwid, kwid, sigma, sigma, 0.0) a, b, theta, ixx, iyy, ixy = quickAndDirtyShape(img, afwGeom.Point2D(kwid/2,kwid/2)) print "planted:", a/sigma, b/sigma, theta, ixx/sigma**2, iyy/sigma**2, ixy/sigma**2 prec = 6 self.assertAlmostEqual(a, sigma, prec) self.assertAlmostEqual(b, sigma, prec) self.assertAlmostEqual(ixx, sigma**2, prec) self.assertAlmostEqual(iyy, sigma**2, prec) # try 4% shear along theta=45 shear = 1.04 q = geomEllip.Quadrupole(geomEllip.Axes(shear*sigma, sigma, math.pi/4.0)) img = plantEllipse(kwid, kwid, q.getIxx(), q.getIyy(), q.getIxy()) a, b, theta, ixx, iyy, ixy = quickAndDirtyShape(img, afwGeom.Point2D(kwid/2,kwid/2)) print "sheared 4%:", a/sigma, b/sigma, theta, ixx/sigma**2, iyy/sigma**2, ixy/sigma**2 self.assertAlmostEqual(a, shear*sigma, prec) self.assertAlmostEqual(b, sigma, prec) self.assertAlmostEqual(theta, 45.0, prec) # now use quickAndDirty to measure the PSFs we created a, b, theta, ixx, iyy, ixy = quickAndDirtyShape(psfImg, p) print "psfImg:", a/psfSigma, b/psfSigma, theta, ixx/psfSigma**2, iyy/psfSigma**2, ixy/psfSigma**2 self.assertAlmostEqual(a, psfSigma, prec) self.assertAlmostEqual(b, psfSigma, prec) print "known Theta = ", thetaKnown a, b, theta, ixx, iyy, ixy = quickAndDirtyShape(psfImgDistInternally, p) print "warpIntern:", a/psfSigma, b/psfSigma, theta, ixx/psfSigma**2, iyy/psfSigma**2, ixy/psfSigma**2 self.assertTrue(abs(a/psfSigma - aKnown) < 0.01) self.assertTrue(abs(b/psfSigma - bKnown) < 0.01) self.assertTrue(abs(theta - thetaKnown) < 0.5) # half a degree a, b, theta, ixx, iyy, ixy = quickAndDirtyShape(psfImgDistByUs, p) print "warpExtern:", a/psfSigma, b/psfSigma, theta, ixx/psfSigma**2, iyy/psfSigma**2, ixy/psfSigma**2 self.assertTrue(abs(a/psfSigma - aKnown) < 0.01) self.assertTrue(abs(b/psfSigma - bKnown) < 0.01) self.assertTrue(abs(theta - thetaKnown) < 0.5)