Coverage for tests/test_makeMatchStatistics.py: 21%

88 statements  

« prev     ^ index     » next       coverage.py v6.4.2, created at 2022-08-06 01:46 -0700

1# 

2# LSST Data Management System 

3# Copyright 2015 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# 

22import unittest 

23import math 

24 

25import numpy as np 

26 

27import lsst.utils.tests 

28import lsst.geom 

29import lsst.afw.geom as afwGeom 

30import lsst.afw.math as afwMath 

31import lsst.afw.table as afwTable 

32from lsst.meas.base import SingleFrameMeasurementTask 

33import lsst.meas.astrom as measAstrom 

34from functools import reduce 

35 

36 

37class TestAstrometricSolver(lsst.utils.tests.TestCase): 

38 

39 def setUp(self): 

40 # make a nominal match list where the distances are 0; test can then modify 

41 # source centroid, reference coord or distance field for each match, as desired 

42 self.wcs = afwGeom.makeSkyWcs(crpix=lsst.geom.Point2D(1500, 1500), 

43 crval=lsst.geom.SpherePoint(215.5, 53.0, lsst.geom.degrees), 

44 cdMatrix=afwGeom.makeCdMatrix(scale=5.1e-5*lsst.geom.degrees)) 

45 self.bboxD = lsst.geom.Box2D(lsst.geom.Point2D(10, 100), lsst.geom.Extent2D(1000, 1500)) 

46 self.numMatches = 25 

47 

48 sourceSchema = afwTable.SourceTable.makeMinimalSchema() 

49 # add centroid (and many other unwanted fields) to sourceSchema 

50 SingleFrameMeasurementTask(schema=sourceSchema) 

51 self.sourceCentroidKey = afwTable.Point2DKey(sourceSchema["slot_Centroid"]) 

52 self.sourceCat = afwTable.SourceCatalog(sourceSchema) 

53 

54 refSchema = afwTable.SourceTable.makeMinimalSchema() 

55 self.refCoordKey = afwTable.CoordKey(refSchema["coord"]) 

56 self.refCat = afwTable.SourceCatalog(refSchema) 

57 

58 self.matchList = [] 

59 

60 np.random.seed(5) 

61 pixPointList = [lsst.geom.Point2D(pos) for pos in 

62 np.random.random_sample([self.numMatches, 2])*self.bboxD.getDimensions() 

63 + self.bboxD.getMin()] 

64 for pixPoint in pixPointList: 

65 src = self.sourceCat.addNew() 

66 src.set(self.sourceCentroidKey, pixPoint) 

67 ref = self.refCat.addNew() 

68 ref.set(self.refCoordKey, self.wcs.pixelToSky(pixPoint)) 

69 

70 match = afwTable.ReferenceMatch(ref, src, 0) 

71 self.matchList.append(match) 

72 

73 def tearDown(self): 

74 del self.wcs 

75 del self.bboxD 

76 del self.sourceCentroidKey 

77 del self.sourceCat 

78 del self.refCoordKey 

79 del self.refCat 

80 del self.matchList 

81 

82 def testMakeMatchStatistics(self): 

83 """Test makeMatchStatistics 

84 """ 

85 np.random.seed(47) 

86 distList = list((np.random.random_sample([self.numMatches]) - 0.5) * 10) 

87 for dist, match in zip(distList, self.matchList): 

88 match.distance = dist 

89 itemList = (afwMath.MEDIAN, afwMath.MEANCLIP, afwMath.STDEV) 

90 itemMask = reduce(lambda a, b: a | b, itemList) 

91 distStats = measAstrom.makeMatchStatistics(self.matchList, itemMask) 

92 directStats = afwMath.makeStatistics(distList, itemMask) 

93 for item in itemList: 

94 self.assertAlmostEqual(distStats.getValue(item), directStats.getValue(item)) 

95 

96 def testMakeMatchStatisticsInRadians(self): 

97 """Test makeMatchStatisticsInRadians 

98 """ 

99 np.random.seed(164) 

100 offLenList = [val*lsst.geom.radians for val in np.random.random_sample([self.numMatches])] 

101 offDirList = [val*lsst.geom.radians for val in np.random.random_sample([self.numMatches])*math.pi*2] 

102 for offLen, offDir, match in zip(offLenList, offDirList, self.matchList): 

103 coord = match.first.get(self.refCoordKey) 

104 offsetCoord = coord.offset(offDir, offLen) 

105 match.first.set(self.refCoordKey, offsetCoord) 

106 itemList = (afwMath.MEDIAN, afwMath.MEANCLIP, afwMath.IQRANGE) 

107 itemMask = reduce(lambda a, b: a | b, itemList) 

108 distStats = measAstrom.makeMatchStatisticsInRadians(self.wcs, self.matchList, itemMask) 

109 distRadiansList = [val.asRadians() for val in offLenList] 

110 directStats = afwMath.makeStatistics(distRadiansList, itemMask) 

111 for item in itemList: 

112 self.assertAlmostEqual(distStats.getValue(item), directStats.getValue(item)) 

113 

114 def testMakeMatchStatisticsInPixels(self): 

115 """Test testMakeMatchStatisticsInPixels 

116 """ 

117 np.random.seed(164) 

118 offList = [lsst.geom.Extent2D(val) for val in (np.random.random_sample([self.numMatches, 2])-0.5)*10] 

119 for off, match in zip(offList, self.matchList): 

120 centroid = match.second.get(self.sourceCentroidKey) 

121 offCentroid = centroid + off 

122 match.second.set(self.sourceCentroidKey, offCentroid) 

123 itemList = (afwMath.MEDIAN, afwMath.MEAN, afwMath.STDEVCLIP) 

124 itemMask = reduce(lambda a, b: a | b, itemList) 

125 distStats = measAstrom.makeMatchStatisticsInPixels(self.wcs, self.matchList, itemMask) 

126 distList = [math.hypot(*val) for val in offList] 

127 directStats = afwMath.makeStatistics(distList, itemMask) 

128 for item in itemList: 

129 self.assertAlmostEqual(distStats.getValue(item), directStats.getValue(item)) 

130 

131 

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

133 pass 

134 

135 

136def setup_module(module): 

137 lsst.utils.tests.init() 

138 

139 

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

141 lsst.utils.tests.init() 

142 unittest.main()