def testLinearize(self): for transform, invertible in ( (afwGeom.TransformPoint2ToPoint2(makeForwardPolyMap(2, 2)), False), (afwGeom.makeIdentityTransform(), True), (afwGeom.makeTransform(lsst.geom.AffineTransform(np.array([[3.0, -2.0], [2.0, -1.0]]))), True), (afwGeom.makeRadialTransform([0.0, 8.0e-05, 0.0, -4.5e-12]), True), ): self.checkLinearize(transform, invertible)
def setUp(self): # Make fake sources self.nSources = 10 self.bbox = geom.Box2I(geom.Point2I(0, 0), geom.Extent2I(1024, 1153)) self.xyLoc = 100 dataset = measTests.TestDataset(self.bbox) for srcIdx in range(self.nSources): dataset.addSource(100000.0, geom.Point2D(srcIdx*self.xyLoc, srcIdx*self.xyLoc)) schema = dataset.makeMinimalSchema() schema.addField("base_PixelFlags_flag", type="Flag") schema.addField("base_PixelFlags_flag_offimage", type="Flag") self.exposure, catalog = dataset.realize( 10.0, schema, randomSeed=1234) for src in catalog: src.setCoord(self.exposure.getWcs().pixelToSky(src.getCentroid())) # Non-invertible WCS to test robustness to distortions. # Coefficients transform (x - 1e-7*x^3 -> x, y -> y); see docs for PolyMap. pixelCoeffs = np.array([[-1.0e-7, 1, 3, 0], [1.0, 1, 1, 0], [1.0, 2, 0, 1], ]) self.exposure.setWcs(afwGeom.makeModifiedWcs( afwGeom.TransformPoint2ToPoint2(ast.PolyMap(pixelCoeffs, 2, options="IterInverse=1")), self.exposure.wcs, modifyActualPixels=False )) # Convert to task required format self.testDiaSources = catalog.asAstropy().to_pandas() self.testDiaSources.rename(columns={"coord_ra": "ra", "coord_dec": "decl"}, inplace=True,) self.testDiaSources.loc[:, "ra"] = np.rad2deg(self.testDiaSources["ra"]) self.testDiaSources.loc[:, "decl"] = np.rad2deg(self.testDiaSources["decl"]) self.testDiaSources["ssObjectId"] = 0 # Grab a subset to treat as solar system objects self.testSsObjects = self.testDiaSources[2:8].reset_index() # Assign them ids starting from 1. self.testSsObjects.loc[:, "ssObjectId"] = np.arange( 1, len(self.testSsObjects) + 1, dtype=int,) self.testSsObjects["Err(arcsec)"] = np.ones(len(self.testSsObjects))
def makeSipIwcToPixel(metadata): """Make an IWC to pixel transform with SIP distortion from FITS-WCS metadata This function is primarily intended for unit tests. IWC is intermediate world coordinates, as described in the FITS papers. Parameters ---------- metadata : lsst.daf.base.PropertySet FITS metadata describing a WCS with inverse SIP coefficients Returns ------- lsst.afw.geom.TransformPoint2ToPoint2 Transform from IWC position to pixel position (zero-based) in the forward direction. The inverse direction is not defined. Notes ----- The inverse SIP terms APn_m, BPn_m are polynomial coefficients x^n y^m for computing transformed x, y respectively. If we call the resulting polynomial inverseSipPolynomial, the returned transformation is: pixelPosition = pixel origin + uv + inverseSipPolynomial(uv) where uv = inverseCdMatrix * iwcPosition """ crpix = (metadata.getScalar("CRPIX1") - 1, metadata.getScalar("CRPIX2") - 1) pixelRelativeToAbsoluteMap = ast.ShiftMap(crpix) cdMatrix = getCdMatrixFromMetadata(metadata) cdMatrixMap = ast.MatrixMap(cdMatrix.copy()) coeffList = makeSipPolyMapCoeffs(metadata, "AP") + makeSipPolyMapCoeffs( metadata, "BP") coeffArr = np.array(coeffList, dtype=float) sipPolyMap = ast.PolyMap(coeffArr, 2, "IterInverse=0") iwcToPixelMap = cdMatrixMap.inverted().then(sipPolyMap).then( pixelRelativeToAbsoluteMap) return afwGeom.TransformPoint2ToPoint2(iwcToPixelMap)
def makeSipPixelToIwc(metadata): """Make a pixel to IWC transform with SIP distortion from FITS-WCS metadata This function is primarily intended for unit tests. IWC is intermediate world coordinates, as described in the FITS papers. Parameters ---------- metadata : lsst.daf.base.PropertySet FITS metadata describing a WCS with forward SIP coefficients Returns ------- lsst.afw.geom.TransformPoint2ToPoint2 Transform from pixel position (zero-based) to IWC position in the forward direction. The inverse direction is not defined. Notes ----- The forward SIP terms An_m, Bn_m are polynomial coefficients x^n y^m for computing transformed x, y respectively. If we call the resulting polynomial sipPolynomial, the returned transformation is: iwcPosition = cdMatrix * (dxy + sipPolynomial(dxy)) where dxy = pixelPosition - pixelOrigin """ crpix = (metadata.get("CRPIX1") - 1, metadata.get("CRPIX2") - 1) pixelAbsoluteToRelativeMap = ast.ShiftMap(crpix).getInverse() cdMatrix = getCdMatrixFromMetadata(metadata) cdMatrixMap = ast.MatrixMap(cdMatrix.copy()) coeffList = makeSipPolyMapCoeffs(metadata, "A") + makeSipPolyMapCoeffs( metadata, "B") coeffArr = np.array(coeffList, dtype=float) sipPolyMap = ast.PolyMap(coeffArr, 2, "IterInverse=0") pixelToIwcMap = pixelAbsoluteToRelativeMap.then(sipPolyMap).then( cdMatrixMap) return afwGeom.TransformPoint2ToPoint2(pixelToIwcMap)