Coverage for tests/test_coaddApCorrMap.py: 20%

111 statements  

« prev     ^ index     » next       coverage.py v7.5.0, created at 2024-04-30 03:11 -0700

1# 

2# LSST Data Management System 

3# 

4# Copyright 2008-2016 AURA/LSST. 

5# 

6# This product includes software developed by the 

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

8# 

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

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

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

12# (at your option) any later version. 

13# 

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

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

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

17# GNU General Public License for more details. 

18# 

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

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

21# see <https://www.lsstcorp.org/LegalNotices/>. 

22# 

23import os 

24import numpy as np 

25import unittest 

26 

27import lsst.geom 

28import lsst.afw.geom as afwGeom 

29import lsst.afw.math as afwMath 

30import lsst.afw.table as afwTable 

31import lsst.afw.image as afwImage 

32import lsst.meas.algorithms as measAlg 

33import lsst.utils.tests 

34 

35try: 

36 type(verbose) 

37except NameError: 

38 verbose = 0 

39 display = False 

40 

41 

42class CoaddApCorrMapTest(lsst.utils.tests.TestCase): 

43 

44 def testCoaddApCorrMap(self): 

45 """Check that we can create and use a coadd ApCorrMap.""" 

46 coaddBox = lsst.geom.Box2I(lsst.geom.Point2I(0, 0), lsst.geom.Extent2I(100, 100)) 

47 scale = 5.0e-5*lsst.geom.degrees 

48 cdMatrix = afwGeom.makeCdMatrix(scale=scale) 

49 crval = lsst.geom.SpherePoint(0.0, 0.0, lsst.geom.degrees) 

50 center = lsst.geom.Point2D(lsst.geom.Extent2D(coaddBox.getDimensions())*0.5) 

51 coaddWcs = afwGeom.makeSkyWcs(crpix=lsst.geom.Point2D(0, 0), crval=crval, cdMatrix=cdMatrix) 

52 schema = afwTable.ExposureTable.makeMinimalSchema() 

53 weightKey = schema.addField("customweightname", type="D", doc="Coadd weight") 

54 catalog = afwTable.ExposureCatalog(schema) 

55 

56 # Non-overlapping 

57 num = 5 

58 inputBox = lsst.geom.Box2I(lsst.geom.Point2I(0, 0), lsst.geom.Extent2I(10, 10)) 

59 validBox = lsst.geom.Box2I(lsst.geom.Point2I(0, 0), lsst.geom.Extent2I(7, 7)) 

60 pointList = [] 

61 pointListValid = [] 

62 

63 for i in range(num): 

64 value = np.array([[1]], dtype=float) # Constant with value = i+1 

65 apCorrMap = afwImage.ApCorrMap() 

66 bf = afwMath.ChebyshevBoundedField(inputBox, value*(i + 1)) 

67 apCorrMap.set("only", bf) 

68 

69 point = lsst.geom.Point2D(0, 0) - lsst.geom.Extent2D(coaddBox.getDimensions())*(i+0.5)/num 

70 wcs = afwGeom.makeSkyWcs(crpix=point, crval=crval, cdMatrix=cdMatrix) 

71 center = inputBox.getCenter() 

72 pointList.append(coaddWcs.skyToPixel(wcs.pixelToSky(center))) 

73 

74 # This point will only be valid for the second overlapping record 

75 pointValid = center + lsst.geom.Extent2D(4, 4) 

76 pointListValid.append(coaddWcs.skyToPixel(wcs.pixelToSky(pointValid))) 

77 

78 # A record with the valid polygon defining a limited region 

79 record = catalog.getTable().makeRecord() 

80 record.setWcs(wcs) 

81 record.setBBox(inputBox) 

82 record.setApCorrMap(apCorrMap) 

83 record.set(weightKey, i + 1) 

84 record['id'] = i 

85 record.setValidPolygon(afwGeom.Polygon(lsst.geom.Box2D(validBox))) 

86 catalog.append(record) 

87 

88 # An overlapping record with the whole region as valid 

89 record = catalog.getTable().makeRecord() 

90 record.setWcs(wcs) 

91 record.setBBox(inputBox) 

92 apCorrMap = afwImage.ApCorrMap() 

93 bf = afwMath.ChebyshevBoundedField(inputBox, value*(i + 2)) 

94 apCorrMap.set("only", bf) 

95 record.setApCorrMap(apCorrMap) 

96 record.set(weightKey, i + 2) 

97 record['id'] = i + num 

98 record.setValidPolygon(afwGeom.Polygon(lsst.geom.Box2D(inputBox))) 

99 catalog.append(record) 

100 

101 apCorrMap = measAlg.makeCoaddApCorrMap(catalog, coaddBox, coaddWcs, "customweightname") 

102 # This will test a point where both records contribute 

103 self.assertApCorrMap(apCorrMap, pointList) 

104 # Only the second record will be valid for this point 

105 self.assertApCorrMapValid(apCorrMap, pointListValid) 

106 

107 filename = os.path.join(os.path.dirname(os.path.realpath(__file__)), "coaddApCorrMap.fits") 

108 exposure = afwImage.ExposureF(1, 1) 

109 exposure.getInfo().setApCorrMap(apCorrMap) 

110 exposure.writeFits(filename) 

111 exposure = afwImage.ExposureF(filename) 

112 self.assertApCorrMap(exposure.getInfo().getApCorrMap(), pointList) 

113 self.assertApCorrMapValid(exposure.getInfo().getApCorrMap(), pointListValid) 

114 os.unlink(filename) 

115 

116 def assertApCorrMap(self, apCorrMap, pointList): 

117 # Check point-by-point. 

118 pointsX = np.zeros(len(pointList)) 

119 pointsY = np.zeros(len(pointList)) 

120 expectedArray = np.zeros(len(pointList)) 

121 for i, point in enumerate(pointList): 

122 weights = [i + 1, i + 2] 

123 values = [i + 1, i + 2] 

124 expected = sum((w*v for w, v in zip(weights, values)), 0.0)/sum(weights) 

125 actual = apCorrMap["only"].evaluate(point) 

126 self.assertEqual(actual, expected) 

127 # Create arrays for vectorized call. 

128 expectedArray[i] = expected 

129 pointsX[i] = point.getX() 

130 pointsY[i] = point.getY() 

131 

132 # Check vectorized 

133 actualArray = apCorrMap["only"].evaluate(pointsX, pointsY) 

134 self.assertFloatsAlmostEqual(actualArray, expectedArray) 

135 

136 # Check vectorized single point. 

137 actualArray0 = apCorrMap["only"].evaluate(pointsX[0], pointsY[0]) 

138 self.assertFloatsAlmostEqual(actualArray0, expectedArray[0]) 

139 

140 def assertApCorrMapValid(self, apCorrMap, pointList): 

141 # Check point-by-point. 

142 pointsX = np.zeros(len(pointList)) 

143 pointsY = np.zeros(len(pointList)) 

144 expectedArray = np.zeros(len(pointList)) 

145 for i, point in enumerate(pointList): 

146 weights = [i + 2] 

147 values = [i + 2] 

148 expected = sum((w*v for w, v in zip(weights, values)), 0.0)/sum(weights) 

149 actual = apCorrMap["only"].evaluate(point) 

150 self.assertEqual(actual, expected) 

151 # Create arrays for vectorized call. 

152 expectedArray[i] = expected 

153 pointsX[i] = point.getX() 

154 pointsY[i] = point.getY() 

155 

156 # Check vectorized 

157 actualArray = apCorrMap["only"].evaluate(pointsX, pointsY) 

158 self.assertFloatsAlmostEqual(actualArray, expectedArray) 

159 

160 

161class TestMemory(lsst.utils.tests.MemoryTestCase): 

162 pass 

163 

164 

165def setup_module(module): 

166 lsst.utils.tests.init() 

167 

168 

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

170 lsst.utils.tests.init() 

171 unittest.main()