Coverage for tests/test_detection.py: 20%

84 statements  

« prev     ^ index     » next       coverage.py v6.5.0, created at 2022-12-01 20:41 +0000

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 unittest 

24import numpy as np 

25 

26import lsst.geom 

27import lsst.afw.table as afwTable 

28import lsst.afw.image as afwImage 

29from lsst.meas.algorithms import SourceDetectionTask 

30from lsst.meas.algorithms.testUtils import plantSources 

31import lsst.utils.tests 

32 

33display = False 

34 

35 

36class DetectionTestCase(lsst.utils.tests.TestCase): 

37 """Test the aperture correction.""" 

38 

39 def testBasics(self): 

40 bbox = lsst.geom.Box2I(lsst.geom.Point2I(256, 100), lsst.geom.Extent2I(128, 127)) 

41 minCounts = 5000 

42 maxCounts = 50000 

43 starSigma = 1.5 

44 numX = 5 

45 numY = 5 

46 coordList = self.makeCoordList( 

47 bbox=bbox, 

48 numX=numX, 

49 numY=numY, 

50 minCounts=minCounts, 

51 maxCounts=maxCounts, 

52 sigma=starSigma, 

53 ) 

54 kwid = 11 

55 sky = 2000 

56 addPoissonNoise = True 

57 exposure = plantSources(bbox=bbox, kwid=kwid, sky=sky, coordList=coordList, 

58 addPoissonNoise=addPoissonNoise) 

59 

60 schema = afwTable.SourceTable.makeMinimalSchema() 

61 config = SourceDetectionTask.ConfigClass() 

62 config.reEstimateBackground = False 

63 task = SourceDetectionTask(config=config, schema=schema) 

64 for doSmooth in (False, True): 

65 taskSigma = 2.2 

66 res = task.detectFootprints(exposure, doSmooth=doSmooth, sigma=taskSigma) 

67 self.assertEqual(res.numPos, numX * numY) 

68 self.assertEqual(res.numNeg, 0) 

69 self.assertEqual(task.metadata.getScalar("sigma"), taskSigma) 

70 self.assertEqual(task.metadata.getScalar("doSmooth"), doSmooth) 

71 self.assertEqual(task.metadata.getScalar("nGrow"), int(taskSigma * config.nSigmaToGrow + 0.5)) 

72 

73 res = task.detectFootprints(exposure, doSmooth=doSmooth, sigma=None) 

74 taskSigma = task.metadata.getScalar("sigma") 

75 self.assertLess(abs(taskSigma - starSigma), 0.1) 

76 self.assertEqual(res.numPos, numX * numY) 

77 self.assertEqual(res.numNeg, 0) 

78 

79 def makeCoordList(self, bbox, numX, numY, minCounts, maxCounts, sigma): 

80 """Make a coordList for plantSources.""" 

81 """ 

82 Coords are uniformly spaced in a rectangular grid, with linearly increasing counts 

83 """ 

84 dX = bbox.getWidth() / float(numX) 

85 dY = bbox.getHeight() / float(numY) 

86 minX = bbox.getMinX() + (dX / 2.0) 

87 minY = bbox.getMinY() + (dY / 2.0) 

88 dCounts = (maxCounts - minCounts) / (numX * numY - 1) 

89 

90 coordList = [] 

91 counts = minCounts 

92 for i in range(numX): 

93 x = minX + (dX * i) 

94 for j in range(numY): 

95 y = minY + (dY * j) 

96 coordList.append([x, y, counts, sigma]) 

97 counts += dCounts 

98 return coordList 

99 

100 def testTempBackgrounds(self): 

101 """Test that the temporary backgrounds we remove are properly restored""" 

102 bbox = lsst.geom.Box2I(lsst.geom.Point2I(12345, 67890), lsst.geom.Extent2I(128, 127)) 

103 original = afwImage.ExposureF(bbox) 

104 rng = np.random.RandomState(123) 

105 original.image.array[:] = rng.normal(size=original.image.array.shape) 

106 original.mask.set(0) 

107 original.variance.set(1.0) 

108 

109 def checkExposure(original, doTempLocalBackground, doTempWideBackground): 

110 config = SourceDetectionTask.ConfigClass() 

111 config.reEstimateBackground = False 

112 config.thresholdType = "pixel_stdev" 

113 config.doTempLocalBackground = doTempLocalBackground 

114 config.doTempWideBackground = doTempWideBackground 

115 schema = afwTable.SourceTable.makeMinimalSchema() 

116 task = SourceDetectionTask(config=config, schema=schema) 

117 

118 exposure = original.clone() 

119 task.detectFootprints(exposure, sigma=3.21) 

120 

121 self.assertFloatsEqual(exposure.image.array, original.image.array) 

122 # Mask is permitted to vary: DETECTED bit gets set 

123 self.assertFloatsEqual(exposure.variance.array, original.variance.array) 

124 

125 checkExposure(original, False, False) 

126 checkExposure(original, True, False) 

127 checkExposure(original, False, True) 

128 checkExposure(original, True, True) 

129 

130 

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

132 pass 

133 

134 

135def setup_module(module): 

136 lsst.utils.tests.init() 

137 

138 

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

140 lsst.utils.tests.init() 

141 unittest.main()