def checkGetInverse(self, fromName, toName): """Test Transform<fromName>To<toName>.getInverse Parameters ---------- fromName, toName : `str` Endpoint name prefix for "from" and "to" endpoints, respectively, e.g. "Point2" for `lsst.afw.geom.Point2Endpoint` """ transformClassName = "Transform{}To{}".format(fromName, toName) TransformClass = getattr(afwGeom, transformClassName) baseMsg = "TransformClass={}".format(TransformClass.__name__) for nIn, nOut in itertools.product(self.goodNAxes[fromName], self.goodNAxes[toName]): msg = "{}, nIn={}, nOut={}".format(baseMsg, nIn, nOut) self.checkInverseMapping( TransformClass, makeTwoWayPolyMap(nIn, nOut), "{}, Map={}".format(msg, "TwoWay")) self.checkInverseMapping( TransformClass, makeForwardPolyMap(nIn, nOut), "{}, Map={}".format(msg, "Forward")) self.checkInverseMapping( TransformClass, makeForwardPolyMap(nOut, nIn).getInverse(), "{}, Map={}".format(msg, "Inverse")) self.checkInverseFrameSet(TransformClass, self.makeGoodFrame(fromName, nIn), self.makeGoodFrame(toName, nOut))
def checkInverted(self, fromName, toName): """Test Transform<fromName>To<toName>.inverted Parameters ---------- fromName, toName : `str` Endpoint name prefix for "from" and "to" endpoints, respectively, e.g. "Point2" for `lsst.afw.geom.Point2Endpoint` """ transformClassName = "Transform{}To{}".format(fromName, toName) TransformClass = getattr(afwGeom, transformClassName) baseMsg = "TransformClass={}".format(TransformClass.__name__) for nIn, nOut in itertools.product(self.goodNAxes[fromName], self.goodNAxes[toName]): msg = "{}, nIn={}, nOut={}".format(baseMsg, nIn, nOut) self.checkInverseMapping( TransformClass, makeTwoWayPolyMap(nIn, nOut), "{}, Map={}".format(msg, "TwoWay")) self.checkInverseMapping( TransformClass, makeForwardPolyMap(nIn, nOut), "{}, Map={}".format(msg, "Forward")) self.checkInverseMapping( TransformClass, makeForwardPolyMap(nOut, nIn).inverted(), "{}, Map={}".format(msg, "Inverse"))
def testThenChaining(self): """Test that the order of chaining Transform.then does not matter Test that A.then(B.then(C)) gives the same transformation as (A.then(B)).then(C) Internal details may differ (e.g. frame indices if the frames in the contained FrameSet), but the mathematical result of the two transforms should be the same. """ transform1 = afwGeom.TransformGenericToGeneric( makeForwardPolyMap(2, 3)) transform2 = afwGeom.TransformGenericToGeneric( makeForwardPolyMap(3, 4)) transform3 = afwGeom.TransformGenericToGeneric( makeForwardPolyMap(4, 1)) merged1 = transform1.then(transform2.then(transform3)) merged2 = transform1.then(transform2).then(transform3) fromEndpoint = transform1.fromEndpoint toEndpoint = transform3.toEndpoint inPoint = fromEndpoint.pointFromData(self.makeRawPointData(2)) assert_allclose(toEndpoint.dataFromPoint(merged1.applyForward(inPoint)), toEndpoint.dataFromPoint(merged2.applyForward(inPoint)))
def checkTransformFromMapping(self, fromName, toName): """Check Transform_<fromName>_<toName> using the Mapping constructor Parameters ---------- fromName, toName : `str` Endpoint name prefix for "from" and "to" endpoints, respectively, e.g. "Point2" for `lsst.afw.geom.Point2Endpoint` fromAxes, toAxes : `int` number of axes in fromFrame and toFrame, respectively """ transformClassName = "Transform{}To{}".format(fromName, toName) TransformClass = getattr(afwGeom, transformClassName) baseMsg = "TransformClass={}".format(TransformClass.__name__) # check valid numbers of inputs and outputs for nIn, nOut in itertools.product(self.goodNAxes[fromName], self.goodNAxes[toName]): msg = "{}, nIn={}, nOut={}".format(baseMsg, nIn, nOut) polyMap = makeTwoWayPolyMap(nIn, nOut) transform = TransformClass(polyMap) # desired output from `str(transform)` desStr = "{}[{}->{}]".format(transformClassName, nIn, nOut) self.assertEqual("{}".format(transform), desStr) self.assertEqual(repr(transform), "lsst.afw.geom." + desStr) self.checkTransformation(transform, polyMap, msg=msg) # Forward transform but no inverse polyMap = makeForwardPolyMap(nIn, nOut) transform = TransformClass(polyMap) self.checkTransformation(transform, polyMap, msg=msg) # Inverse transform but no forward polyMap = makeForwardPolyMap(nOut, nIn).inverted() transform = TransformClass(polyMap) self.checkTransformation(transform, polyMap, msg=msg) # check invalid # of output against valid # of inputs for nIn, badNOut in itertools.product(self.goodNAxes[fromName], self.badNAxes[toName]): badPolyMap = makeTwoWayPolyMap(nIn, badNOut) msg = "{}, nIn={}, badNOut={}".format(baseMsg, nIn, badNOut) with self.assertRaises(InvalidParameterError, msg=msg): TransformClass(badPolyMap) # check invalid # of inputs against valid and invalid # of outputs for badNIn, nOut in itertools.product( self.badNAxes[fromName], self.goodNAxes[toName] + self.badNAxes[toName]): badPolyMap = makeTwoWayPolyMap(badNIn, nOut) msg = "{}, badNIn={}, nOut={}".format(baseMsg, nIn, nOut) with self.assertRaises(InvalidParameterError, msg=msg): TransformClass(badPolyMap)
def checkTransformFromMapping(self, fromName, toName): """Check Transform_<fromName>_<toName> using the Mapping constructor Parameters ---------- fromName, toName : `str` Endpoint name prefix for "from" and "to" endpoints, respectively, e.g. "Point2" for `lsst.afw.geom.Point2Endpoint` fromAxes, toAxes : `int` number of axes in fromFrame and toFrame, respectively """ transformClassName = "Transform{}To{}".format(fromName, toName) TransformClass = getattr(afwGeom, transformClassName) baseMsg = "TransformClass={}".format(TransformClass.__name__) # check valid numbers of inputs and outputs for nIn, nOut in itertools.product(self.goodNAxes[fromName], self.goodNAxes[toName]): msg = "{}, nIn={}, nOut={}".format(baseMsg, nIn, nOut) polyMap = makeTwoWayPolyMap(nIn, nOut) transform = TransformClass(polyMap) # desired output from `str(transform)` desStr = "{}[{}->{}]".format(transformClassName, nIn, nOut) self.assertEqual("{}".format(transform), desStr) self.assertEqual(repr(transform), "lsst.afw.geom." + desStr) self.checkTransformation(transform, polyMap, msg=msg) # Forward transform but no inverse polyMap = makeForwardPolyMap(nIn, nOut) transform = TransformClass(polyMap) self.checkTransformation(transform, polyMap, msg=msg) # Inverse transform but no forward polyMap = makeForwardPolyMap(nOut, nIn).inverted() transform = TransformClass(polyMap) self.checkTransformation(transform, polyMap, msg=msg) # check invalid # of output against valid # of inputs for nIn, badNOut in itertools.product(self.goodNAxes[fromName], self.badNAxes[toName]): badPolyMap = makeTwoWayPolyMap(nIn, badNOut) msg = "{}, nIn={}, badNOut={}".format(baseMsg, nIn, badNOut) with self.assertRaises(InvalidParameterError, msg=msg): TransformClass(badPolyMap) # check invalid # of inputs against valid and invalid # of outputs for badNIn, nOut in itertools.product(self.badNAxes[fromName], self.goodNAxes[toName] + self.badNAxes[toName]): badPolyMap = makeTwoWayPolyMap(badNIn, nOut) msg = "{}, badNIn={}, nOut={}".format(baseMsg, nIn, nOut) with self.assertRaises(InvalidParameterError, msg=msg): TransformClass(badPolyMap)
def testThen(self): """Test that Transform.then behaves as expected """ transform1 = afwGeom.TransformGenericToGeneric( makeForwardPolyMap(2, 3)) transform2 = afwGeom.TransformGenericToGeneric( makeForwardPolyMap(3, 4)) for simplify in (False, True): merged = transform1.then(transform2, simplify=simplify) inPoint = self.makeRawPointData(2) assert_allclose(merged.applyForward(inPoint), transform2.applyForward(transform1.applyForward(inPoint)))
def checkGetJacobian(self, fromName, toName): """Test Transform<fromName>To<toName>.getJacobian Parameters ---------- fromName, toName : `str` Endpoint name prefix for "from" and "to" endpoints, respectively, e.g. "Point2" for `lsst.afw.geom.Point2Endpoint` """ transformClassName = "Transform{}To{}".format(fromName, toName) TransformClass = getattr(afwGeom, transformClassName) baseMsg = "TransformClass={}".format(TransformClass.__name__) for nIn, nOut in itertools.product(self.goodNAxes[fromName], self.goodNAxes[toName]): msg = "{}, nIn={}, nOut={}".format(baseMsg, nIn, nOut) polyMap = makeForwardPolyMap(nIn, nOut) transform = TransformClass(polyMap) fromEndpoint = transform.fromEndpoint # Test multiple points to ensure correct functional form rawInPoint = self.makeRawPointData(nIn) inPoint = fromEndpoint.pointFromData(rawInPoint) jacobian = transform.getJacobian(inPoint) assert_allclose(jacobian, self.makeJacobian(nIn, nOut, rawInPoint), err_msg=msg) rawInPoint = self.makeRawPointData(nIn, 0.111) inPoint = fromEndpoint.pointFromData(rawInPoint) jacobian = transform.getJacobian(inPoint) assert_allclose(jacobian, self.makeJacobian(nIn, nOut, rawInPoint), err_msg=msg)
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 testThenChaining(self): """Test that the order of chaining Transform.then does not matter Test that A.then(B.then(C)) gives the same transformation as (A.then(B)).then(C) Internal details may differ, but the mathematical result of the two transforms should be the same. """ transform1 = afwGeom.TransformGenericToGeneric( makeForwardPolyMap(2, 3)) transform2 = afwGeom.TransformGenericToGeneric( makeForwardPolyMap(3, 4)) transform3 = afwGeom.TransformGenericToGeneric( makeForwardPolyMap(4, 1)) merged1 = transform1.then(transform2.then(transform3)) merged2 = transform1.then(transform2).then(transform3) inPoint = self.makeRawPointData(2) assert_allclose(merged1.applyForward(inPoint), merged2.applyForward(inPoint))
def test_MakeRadialMappingErrorHandling(self): """Test error handling in makeRadialMapping""" for bad_nin in (1, 2, 3): for bad_nout in (1, 2, 3): if bad_nin == bad_nout == 1: continue # the only valid case bad_mapping1d = makeForwardPolyMap(bad_nin, bad_nout) with self.assertRaises(ValueError): ast.makeRadialMapping([0.0], bad_mapping1d) mapping1d = ast.ZoomMap(1, 5.5) with self.assertRaises(RuntimeError): ast.makeRadialMapping([], mapping1d)
def test_AppendMismatch(self): """Check that append behaves as expected when joining non-identical frames. """ set1 = self.makeFrameSet(3, 2) set2 = self.makeFrameSet(2, 3) set1.addFrame(FrameSet.CURRENT, makeForwardPolyMap(2, 2), SkyFrame("Ident=sky")) set12 = append(set1, set2) x = [1.2, 3.4, 5.6] y_merged = set12.applyForward(x) y_separate = set2.applyForward(set1.applyForward(x)) assert_allclose(y_merged, y_separate) iFrom = set1.current iTo = set1.nFrame + set2.base self.assertIsInstance(set12.getFrame(iFrom), SkyFrame) self.assertNotIsInstance(set12.getFrame(iTo), SkyFrame) self.assertIsInstance(set12.getMapping(iFrom, iTo), UnitMap)
def test_AppendIndependent(self): """Check that a concatenated FrameSet is not affected by changes to its constituents. """ set1 = self.makeFrameSet(3, 3) set2 = self.makeFrameSet(3, 3) set12 = append(set1, set2) nTotal = set12.nFrame x = [1.2, 3.4, 5.6] y = set12.applyForward(x) set1.addFrame(2, makeTwoWayPolyMap(4, 2), Frame(2, "Ident=extra")) set1.addFrame(1, makeTwoWayPolyMap(3, 3), Frame(3, "Ident=legume")) set1.removeFrame(3) set2.addFrame(4, makeForwardPolyMap(1, 4), Frame(4, "Ident=extra")) set2.base = 2 # Use exact equality because nothing should change self.assertEqual(set12.nFrame, nTotal) self.assertEqual(set12.applyForward(x), y)
def test_AppendIndependent(self): """Check that a concatenated FrameSet is not affected by changes to its constituents. """ set1 = self.makeFrameSet(3, 3) set2 = self.makeFrameSet(3, 3) set12 = append(set1, set2) nTotal = set12.nFrame x = [1.2, 3.4, 5.6] y = set12.applyForward(x) set1.addFrame(2, makeTwoWayPolyMap(4, 2), Frame(2, "Ident=extra")) set1.addFrame(1, makeTwoWayPolyMap(3, 3), Frame(3, "Ident=legume")) set1.removeFrame(3) set2.addFrame(4, makeForwardPolyMap(1, 4), Frame(4, "Ident=extra")) set2.base = 2 # Use exact equality because nothing should change self.assertEquals(set12.nFrame, nTotal) self.assertEquals(set12.applyForward(x), y)