Coverage for tests/test_generalShapeletPsfModels.py: 23%

130 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2023-07-13 11:31 +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 

25import os 

26 

27import lsst.utils.tests 

28import lsst.shapelet 

29import lsst.geom 

30import lsst.afw.geom.ellipses 

31import lsst.afw.table 

32import lsst.afw.detection 

33import lsst.log 

34import lsst.utils.logging 

35import lsst.meas.modelfit 

36import lsst.meas.base 

37import lsst.meas.algorithms 

38 

39# Set trace to 0-5 to view debug messages. Level 5 enables all traces. 

40lsst.utils.logging.trace_set_at("lsst.meas.modelfit.optimizer.Optimizer", -1) 

41lsst.utils.logging.trace_set_at("lsst.meas.modelfit.optimizer.solveTrustRegion", -1) 

42 

43 

44class GeneralShapeletPsfApproxPluginsTestCase(lsst.utils.tests.TestCase): 

45 

46 def setUp(self): 

47 numpy.random.seed(500) 

48 self.exposure = lsst.afw.image.ExposureF(41, 41) 

49 self.schema = lsst.afw.table.SourceTable.makeMinimalSchema() 

50 self.centroidKey = lsst.afw.table.Point2DKey.addFields(self.schema, "centroid", "centroid", "pixel") 

51 self.schema.getAliasMap().set("slot_Centroid", "centroid") 

52 self.psfDir = os.path.join(os.environ["MEAS_MODELFIT_DIR"], "tests", "data", "psfs") 

53 

54 def tearDown(self): 

55 del self.exposure 

56 del self.schema 

57 del self.centroidKey 

58 del self.psfDir 

59 

60 def makePsf(self, psfname, max=None): 

61 data = lsst.afw.image.ImageF(os.path.join(self.psfDir, psfname)).getArray().astype(numpy.float64) 

62 if max is not None: 

63 trim0 = (data.shape[0] - max)//2 

64 trim1 = (data.shape[1] - max)//2 

65 if trim0 > 0 and trim1 > 0: 

66 data = data[trim0:trim0+max, trim1:trim1+max] 

67 kernel = lsst.afw.math.FixedKernel(lsst.afw.image.ImageD(data)) 

68 return lsst.meas.algorithms.KernelPsf(kernel) 

69 

70 def runTask(self, psftype, sequence): 

71 config = lsst.meas.base.SingleFrameMeasurementTask.ConfigClass() 

72 config.slots.centroid = None 

73 config.slots.shape = None 

74 config.slots.psfFlux = None 

75 config.slots.apFlux = None 

76 config.slots.gaussianFlux = None 

77 config.slots.modelFlux = None 

78 config.slots.calibFlux = None 

79 config.doReplaceWithNoise = False 

80 config.plugins.names = ["modelfit_GeneralShapeletPsfApprox"] 

81 config.plugins["modelfit_GeneralShapeletPsfApprox"].sequence = sequence 

82 task = lsst.meas.base.SingleFrameMeasurementTask(config=config, schema=self.schema) 

83 measCat = lsst.afw.table.SourceCatalog(self.schema) 

84 measRecord = measCat.addNew() 

85 measRecord.set(self.centroidKey, lsst.geom.Point2D(20.0, 20.0)) 

86 measRecord.set(self.centroidKey, lsst.geom.Point2D(20.0, 20.0)) 

87 task.run(measCat, self.exposure) 

88 return measRecord 

89 

90 def testSingleGaussian(self): 

91 sigma1 = 3.0 

92 self.exposure.setPsf(lsst.afw.detection.GaussianPsf(19, 19, sigma1)) 

93 measRecord = self.runTask("Single Gaussian Psf", ["SingleGaussian"]) 

94 keySingleGaussian = lsst.shapelet.MultiShapeletFunctionKey( 

95 self.schema["modelfit"]["GeneralShapeletPsfApprox"]["SingleGaussian"] 

96 ) 

97 msfSingleGaussian = measRecord.get(keySingleGaussian) 

98 self.assertEqual(len(msfSingleGaussian.getComponents()), 1) 

99 comps = msfSingleGaussian.getComponents() 

100 r0 = comps[0].getEllipse().getCore().getDeterminantRadius() 

101 self.assertFloatsAlmostEqual(r0, sigma1, .05) 

102 

103 def testDoubleGaussian(self): 

104 sigma1 = 2.0 

105 sigma2 = 4.0 

106 self.exposure.setPsf(lsst.meas.algorithms.DoubleGaussianPsf(19, 19, sigma1, sigma2, .25)) 

107 measRecord = self.runTask("Double Gaussian Psf", ["DoubleGaussian"]) 

108 keyDoubleGaussian = lsst.shapelet.MultiShapeletFunctionKey( 

109 self.schema["modelfit"]["GeneralShapeletPsfApprox"]["DoubleGaussian"] 

110 ) 

111 msf = measRecord.get(keyDoubleGaussian) 

112 comps = msf.getComponents() 

113 self.assertEqual(len(comps), 2) 

114 # amplitudes are equal by construction 

115 A0 = measRecord.get("modelfit_GeneralShapeletPsfApprox_DoubleGaussian_0_0") 

116 A1 = measRecord.get("modelfit_GeneralShapeletPsfApprox_DoubleGaussian_1_0") 

117 self.assertFloatsAlmostEqual(A0, A1, .05) 

118 r0 = comps[0].getEllipse().getCore().getDeterminantRadius() 

119 r1 = comps[1].getEllipse().getCore().getDeterminantRadius() 

120 self.assertFloatsAlmostEqual(r0, sigma1, .05) 

121 self.assertFloatsAlmostEqual(r1, sigma2, .05) 

122 

123 def testDoubleShapelet(self): 

124 self.exposure.setPsf(self.makePsf("galsimPsf_0.5.fits", max=33)) 

125 measRecord = self.runTask("Galsim Psf", ["DoubleShapelet"]) 

126 keyDoubleShapelet = lsst.shapelet.MultiShapeletFunctionKey( 

127 self.schema["modelfit"]["GeneralShapeletPsfApprox"]["DoubleShapelet"] 

128 ) 

129 msf = measRecord.get(keyDoubleShapelet) 

130 comps = msf.getComponents() 

131 self.assertEqual(len(comps), 2) 

132 A0 = measRecord.get("modelfit_GeneralShapeletPsfApprox_DoubleShapelet_0_0") 

133 A1 = measRecord.get("modelfit_GeneralShapeletPsfApprox_DoubleShapelet_1_0") 

134 self.assertGreater(A1, .04) 

135 self.assertGreater(A0, .04) 

136 

137 def testFull(self): 

138 self.exposure.setPsf(self.makePsf("galsimPsf_0.9.fits", max=33)) 

139 measRecord = self.runTask("Galsim Psf", ["Full"]) 

140 keyFull = lsst.shapelet.MultiShapeletFunctionKey( 

141 self.schema["modelfit"]["GeneralShapeletPsfApprox"]["Full"] 

142 ) 

143 msf = measRecord.get(keyFull) 

144 comps = msf.getComponents() 

145 self.assertEqual(len(comps), 4) 

146 A1 = measRecord.get("modelfit_GeneralShapeletPsfApprox_Full_1_0") 

147 A2 = measRecord.get("modelfit_GeneralShapeletPsfApprox_Full_2_0") 

148 # test the primary and wings to be sure we are getting something 

149 self.assertGreater(A2, .04) 

150 self.assertGreater(A1, .04) 

151 

152 def testSequence(self): 

153 sigma1 = 2.0 

154 sigma2 = 4.0 

155 self.exposure.setPsf(lsst.meas.algorithms.DoubleGaussianPsf(19, 19, sigma1, sigma2, .25)) 

156 measRecord = self.runTask("Single Gaussian Psf", ["SingleGaussian", "DoubleGaussian", 

157 "DoubleShapelet"]) 

158 keySingleGaussian = lsst.shapelet.MultiShapeletFunctionKey( 

159 self.schema["modelfit"]["GeneralShapeletPsfApprox"]["SingleGaussian"] 

160 ) 

161 msfSingleGaussian = measRecord.get(keySingleGaussian) 

162 self.assertEqual(len(msfSingleGaussian.getComponents()), 1) 

163 comps = msfSingleGaussian.getComponents() 

164 r0 = comps[0].getEllipse().getCore().getDeterminantRadius() 

165 # don't expect it to be all that close, but the DoubleGaussian should be 

166 self.assertFloatsAlmostEqual(r0, sigma1, .3) 

167 

168 keyDoubleGaussian = lsst.shapelet.MultiShapeletFunctionKey( 

169 self.schema["modelfit"]["GeneralShapeletPsfApprox"]["DoubleGaussian"] 

170 ) 

171 msfDoubleGaussian = measRecord.get(keyDoubleGaussian) 

172 comps = msfDoubleGaussian.getComponents() 

173 r0 = comps[0].getEllipse().getCore().getDeterminantRadius() 

174 r1 = comps[1].getEllipse().getCore().getDeterminantRadius() 

175 self.assertFloatsAlmostEqual(r0, sigma1, .05) 

176 self.assertFloatsAlmostEqual(r1, sigma2, .05) 

177 

178 

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

180 pass 

181 

182 

183def setup_module(module): 

184 lsst.utils.tests.init() 

185 

186 

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

188 lsst.utils.tests.init() 

189 unittest.main()