Coverage for tests/test_projection.py: 30%

61 statements  

« prev     ^ index     » next       coverage.py v6.4.1, created at 2022-06-09 02:57 -0700

1# 

2# LSST Data Management System 

3# Copyright 2008-2017 LSST Corporation. 

4# 

5# This product includes software developed by the 

6# LSST Project (http://www.lsst.org/). 

7# 

8# This program is free software: you can redistribute it and/or modify 

9# it under the terms of the GNU General Public License as published by 

10# the Free Software Foundation, either version 3 of the License, or 

11# (at your option) any later version. 

12# 

13# This program is distributed in the hope that it will be useful, 

14# but WITHOUT ANY WARRANTY; without even the implied warranty of 

15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

16# GNU General Public License for more details. 

17# 

18# You should have received a copy of the LSST License Statement and 

19# the GNU General Public License along with this program. If not, 

20# see <http://www.lsstcorp.org/LegalNotices/>. 

21# 

22 

23import unittest 

24 

25import numpy as np 

26 

27import lsst.geom 

28import lsst.utils.tests 

29import lsst.pex.exceptions 

30import lsst.afw.geom.ellipses 

31import lsst.shapelet.tests 

32import lsst.afw.image 

33 

34 

35class ProjectionTestCase(lsst.shapelet.tests.ShapeletTestCase): 

36 

37 def setUp(self): 

38 np.random.seed(500) 

39 self.ghp = lsst.shapelet.GaussHermiteProjection(16) 

40 

41 def testRotation(self): 

42 order = 4 

43 size = lsst.shapelet.computeSize(order) 

44 nPoints = 100 

45 unitCircle = lsst.afw.geom.ellipses.Ellipse(lsst.afw.geom.ellipses.Quadrupole(1.0, 1.0, 0.0)) 

46 # This matrix should represent a pure rotation in shapelet space, which can be done exactly. 

47 inputTransform = lsst.geom.LinearTransform.makeRotation(0.0*lsst.geom.radians) 

48 outputTransform = lsst.geom.LinearTransform.makeRotation(np.pi/3*lsst.geom.radians) 

49 m = self.ghp.compute(inputTransform, order, outputTransform, order) 

50 # If we apply a rotation by np.pi/3 six times, we should get back where we started with. 

51 self.assertFloatsAlmostEqual(np.linalg.matrix_power(m, 6), 

52 np.identity(size), rtol=1E-14, atol=1E-14) 

53 # Now we test that we get the same result (up to round-off error) for a bunch of test points. 

54 inputTestPoints = np.random.randn(2, nPoints) 

55 outputTestPoints = np.dot(outputTransform.getMatrix(), inputTestPoints) 

56 inputBuilder = lsst.shapelet.MatrixBuilderD.Factory(inputTestPoints[0, :], 

57 inputTestPoints[1, :], order)() 

58 outputBuilder = lsst.shapelet.MatrixBuilderD.Factory(outputTestPoints[0, :], 

59 outputTestPoints[1, :], order)() 

60 inputBasis = inputBuilder(unitCircle) 

61 outputBasis = outputBuilder(unitCircle) 

62 self.assertFloatsAlmostEqual(np.dot(outputBasis, m), inputBasis, rtol=1E-13) 

63 

64 def testPerturbation(self): 

65 inputEllipse = lsst.afw.geom.ellipses.Quadrupole(2.0, 2.0, 0.0) 

66 outputEllipse = lsst.afw.geom.ellipses.Quadrupole(2.01, 2.0, 0.02) 

67 inputShapelet = lsst.shapelet.ShapeletFunction(2, lsst.shapelet.HERMITE, 

68 lsst.afw.geom.ellipses.Ellipse(inputEllipse)) 

69 outputShapelet = lsst.shapelet.ShapeletFunction(8, lsst.shapelet.HERMITE, 

70 lsst.afw.geom.ellipses.Ellipse(outputEllipse)) 

71 m = self.ghp.compute(inputEllipse, inputShapelet.getOrder(), 

72 outputEllipse, outputShapelet.getOrder()) 

73 x = np.random.randn(50) 

74 y = np.random.randn(50) 

75 for i, nx, ny in lsst.shapelet.HermiteIndexGenerator(2): 

76 inputShapelet.getCoefficients()[:] = 0.0 

77 inputShapelet.getCoefficients()[i] = 1.0 

78 outputShapelet.getCoefficients()[:] = np.dot(m, inputShapelet.getCoefficients()) 

79 inputEv = inputShapelet.evaluate() 

80 outputEv = outputShapelet.evaluate() 

81 inputZ = np.array([inputEv(px, py) for px, py in zip(x, y)]) 

82 outputZ = np.array([outputEv(px, py) for px, py in zip(x, y)]) 

83 # tolerances here aren't rigorous, because we're testing an approximation without 

84 # computing how good it should be; it's mostly just a regression/sanity test 

85 self.assertFloatsAlmostEqual(inputZ, outputZ, rtol=5E-3) 

86 

87 def testConvolution0(self): 

88 """Test that the specialization for zeroth-order convolution produces the same tensor 

89 as the general case, which is tested more rigorously elsewhere.""" 

90 psf = self.makeRandomShapeletFunction(order=4) 

91 ellipse1 = lsst.afw.geom.ellipses.Ellipse(lsst.afw.geom.ellipses.Quadrupole(2.0, 3.0, 1.0)) 

92 ellipse2 = lsst.afw.geom.ellipses.Ellipse(ellipse1) 

93 ghcN = lsst.shapelet.GaussHermiteConvolution(1, psf) 

94 ghc0 = lsst.shapelet.GaussHermiteConvolution(0, psf) 

95 rN = ghcN.evaluate(ellipse1) 

96 r0 = ghc0.evaluate(ellipse2) 

97 self.assertFloatsAlmostEqual(rN[:15, 0], r0[:15, 0], rtol=1E-14) 

98 

99 

100class MemoryTester(lsst.utils.tests.MemoryTestCase): 

101 pass 

102 

103 

104def setup_module(module): 

105 lsst.utils.tests.init() 

106 

107 

108if __name__ == "__main__": 108 ↛ 109line 108 didn't jump to line 109, because the condition on line 108 was never true

109 lsst.utils.tests.init() 

110 unittest.main()