Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1from builtins import zip 

2from builtins import range 

3import os 

4import numpy as np 

5import unittest 

6import lsst.utils 

7import lsst.utils.tests 

8from lsst.sims.utils import ObservationMetaData 

9import lsst.sims.photUtils.SignalToNoise as snr 

10from lsst.sims.photUtils import Sed, Bandpass, PhotometricParameters, LSSTdefaults 

11from lsst.sims.photUtils.utils import setM5 

12 

13 

14def setup_module(module): 

15 lsst.utils.tests.init() 

16 

17 

18class TestSNRmethods(unittest.TestCase): 

19 

20 def setUp(self): 

21 

22 starName = os.path.join(lsst.utils.getPackageDir('sims_photUtils'), 

23 'tests/cartoonSedTestData/starSed/') 

24 starName = os.path.join(starName, 'kurucz', 'km20_5750.fits_g40_5790.gz') 

25 self.starSED = Sed() 

26 self.starSED.readSED_flambda(starName) 

27 imsimband = Bandpass() 

28 imsimband.imsimBandpass() 

29 fNorm = self.starSED.calcFluxNorm(22.0, imsimband) 

30 self.starSED.multiplyFluxNorm(fNorm) 

31 

32 hardwareDir = os.path.join(lsst.utils.getPackageDir('throughputs'), 'baseline') 

33 componentList = ['detector.dat', 'm1.dat', 'm2.dat', 'm3.dat', 

34 'lens1.dat', 'lens2.dat', 'lens3.dat'] 

35 self.skySed = Sed() 

36 self.skySed.readSED_flambda(os.path.join(hardwareDir, 'darksky.dat')) 

37 

38 totalNameList = ['total_u.dat', 'total_g.dat', 'total_r.dat', 'total_i.dat', 

39 'total_z.dat', 'total_y.dat'] 

40 

41 self.bpList = [] 

42 self.hardwareList = [] 

43 for name in totalNameList: 

44 dummy = Bandpass() 

45 dummy.readThroughput(os.path.join(hardwareDir, name)) 

46 self.bpList.append(dummy) 

47 

48 dummy = Bandpass() 

49 hardwareNameList = [os.path.join(hardwareDir, name)] 

50 for component in componentList: 

51 hardwareNameList.append(os.path.join(hardwareDir, component)) 

52 dummy.readThroughputList(hardwareNameList) 

53 self.hardwareList.append(dummy) 

54 

55 self.filterNameList = ['u', 'g', 'r', 'i', 'z', 'y'] 

56 

57 def testMagError(self): 

58 """ 

59 Make sure that calcMagError_sed and calcMagError_m5 

60 agree to within 0.001 

61 """ 

62 defaults = LSSTdefaults() 

63 photParams = PhotometricParameters() 

64 

65 # create a cartoon spectrum to test on 

66 spectrum = Sed() 

67 spectrum.setFlatSED() 

68 spectrum.multiplyFluxNorm(1.0e-9) 

69 

70 # find the magnitudes of that spectrum in our bandpasses 

71 magList = [] 

72 for total in self.bpList: 

73 magList.append(spectrum.calcMag(total)) 

74 magList = np.array(magList) 

75 

76 # try for different normalizations of the skySED 

77 for fNorm in np.arange(1.0, 5.0, 1.0): 

78 self.skySed.multiplyFluxNorm(fNorm) 

79 

80 for total, hardware, filterName, mm in \ 

81 zip(self.bpList, self.hardwareList, self.filterNameList, magList): 

82 

83 FWHMeff = defaults.FWHMeff(filterName) 

84 

85 m5 = snr.calcM5(self.skySed, total, hardware, photParams, FWHMeff=FWHMeff) 

86 

87 sigma_sed = snr.calcMagError_sed(spectrum, total, self.skySed, 

88 hardware, photParams, FWHMeff=FWHMeff) 

89 

90 sigma_m5, gamma = snr.calcMagError_m5(mm, total, m5, photParams) 

91 

92 self.assertAlmostEqual(sigma_m5, sigma_sed, 3) 

93 

94 def testVerboseSNR(self): 

95 """ 

96 Make sure that calcSNR_sed has everything it needs to run in verbose mode 

97 """ 

98 photParams = PhotometricParameters() 

99 

100 # create a cartoon spectrum to test on 

101 spectrum = Sed() 

102 spectrum.setFlatSED() 

103 spectrum.multiplyFluxNorm(1.0e-9) 

104 

105 snr.calcSNR_sed(spectrum, self.bpList[0], self.skySed, 

106 self.hardwareList[0], photParams, FWHMeff=0.7, verbose=True) 

107 

108 def testSignalToNoise(self): 

109 """ 

110 Test that calcSNR_m5 and calcSNR_sed give similar results 

111 """ 

112 defaults = LSSTdefaults() 

113 photParams = PhotometricParameters() 

114 

115 m5 = [] 

116 for i in range(len(self.hardwareList)): 

117 m5.append(snr.calcM5(self.skySed, self.bpList[i], 

118 self.hardwareList[i], 

119 photParams, FWHMeff=defaults.FWHMeff(self.filterNameList[i]))) 

120 

121 sedDir = os.path.join(lsst.utils.getPackageDir('sims_photUtils'), 

122 'tests/cartoonSedTestData/starSed/') 

123 sedDir = os.path.join(sedDir, 'kurucz') 

124 fileNameList = os.listdir(sedDir) 

125 

126 rng = np.random.RandomState(42) 

127 offset = rng.random_sample(len(fileNameList))*2.0 

128 

129 for ix, name in enumerate(fileNameList): 

130 if ix > 100: 

131 break 

132 spectrum = Sed() 

133 spectrum.readSED_flambda(os.path.join(sedDir, name)) 

134 ff = spectrum.calcFluxNorm(m5[2]-offset[ix], self.bpList[2]) 

135 spectrum.multiplyFluxNorm(ff) 

136 for i in range(len(self.bpList)): 

137 control_snr = snr.calcSNR_sed(spectrum, self.bpList[i], 

138 self.skySed, 

139 self.hardwareList[i], 

140 photParams, defaults.FWHMeff(self.filterNameList[i])) 

141 

142 mag = spectrum.calcMag(self.bpList[i]) 

143 

144 test_snr, gamma = snr.calcSNR_m5(mag, self.bpList[i], m5[i], photParams) 

145 self.assertLess((test_snr-control_snr)/control_snr, 0.001) 

146 

147 def testSystematicUncertainty(self): 

148 """ 

149 Test that systematic uncertainty is added correctly. 

150 """ 

151 sigmaSys = 0.002 

152 m5_list = [23.5, 24.3, 22.1, 20.0, 19.5, 21.7] 

153 photParams = PhotometricParameters(sigmaSys=sigmaSys) 

154 

155 obs_metadata = ObservationMetaData(pointingRA=23.0, pointingDec=45.0, 

156 m5=m5_list, bandpassName=self.filterNameList) 

157 magnitude_list = [] 

158 for bp in self.bpList: 

159 mag = self.starSED.calcMag(bp) 

160 magnitude_list.append(mag) 

161 

162 for bp, hardware, filterName, mm, m5 in \ 

163 zip(self.bpList, self.hardwareList, self.filterNameList, magnitude_list, m5_list): 

164 

165 skyDummy = Sed() 

166 skyDummy.readSED_flambda(os.path.join(lsst.utils.getPackageDir('throughputs'), 

167 'baseline', 'darksky.dat')) 

168 

169 normalizedSkyDummy = setM5(obs_metadata.m5[filterName], skyDummy, 

170 bp, hardware, 

171 FWHMeff=LSSTdefaults().FWHMeff(filterName), 

172 photParams=photParams) 

173 

174 sigma, gamma = snr.calcMagError_m5(mm, bp, m5, photParams) 

175 

176 snrat = snr.calcSNR_sed(self.starSED, bp, normalizedSkyDummy, hardware, 

177 FWHMeff=LSSTdefaults().FWHMeff(filterName), 

178 photParams=PhotometricParameters()) 

179 

180 testSNR, gamma = snr.calcSNR_m5(mm, bp, m5, photParams=PhotometricParameters(sigmaSys=0.0)) 

181 

182 self.assertAlmostEqual(snrat, testSNR, 10, 

183 msg = 'failed on calcSNR_m5 test %e != %e ' 

184 % (snrat, testSNR)) 

185 

186 control = np.sqrt(np.power(snr.magErrorFromSNR(testSNR), 2) + np.power(sigmaSys, 2)) 

187 

188 msg = '%e is not %e; failed' % (sigma, control) 

189 

190 self.assertAlmostEqual(sigma, control, 10, msg=msg) 

191 

192 def testNoSystematicUncertainty(self): 

193 """ 

194 Test that systematic uncertainty is handled correctly when set to None. 

195 """ 

196 m5_list = [23.5, 24.3, 22.1, 20.0, 19.5, 21.7] 

197 photParams = PhotometricParameters(sigmaSys=0.0) 

198 

199 obs_metadata = ObservationMetaData(pointingRA=23.0, pointingDec=45.0, 

200 m5=m5_list, bandpassName=self.filterNameList) 

201 

202 magnitude_list = [] 

203 for bp in self.bpList: 

204 mag = self.starSED.calcMag(bp) 

205 magnitude_list.append(mag) 

206 

207 for bp, hardware, filterName, mm, m5 in \ 

208 zip(self.bpList, self.hardwareList, self.filterNameList, magnitude_list, m5_list): 

209 

210 skyDummy = Sed() 

211 skyDummy.readSED_flambda(os.path.join(lsst.utils.getPackageDir('throughputs'), 

212 'baseline', 'darksky.dat')) 

213 

214 normalizedSkyDummy = setM5(obs_metadata.m5[filterName], skyDummy, 

215 bp, hardware, 

216 FWHMeff=LSSTdefaults().FWHMeff(filterName), 

217 photParams=photParams) 

218 

219 sigma, gamma = snr.calcMagError_m5(mm, bp, m5, photParams) 

220 

221 snrat = snr.calcSNR_sed(self.starSED, bp, normalizedSkyDummy, hardware, 

222 FWHMeff=LSSTdefaults().FWHMeff(filterName), 

223 photParams=PhotometricParameters()) 

224 

225 testSNR, gamma = snr.calcSNR_m5(mm, bp, m5, photParams=PhotometricParameters(sigmaSys=0.0)) 

226 

227 self.assertAlmostEqual(snrat, testSNR, 10, 

228 msg = 'failed on calcSNR_m5 test %e != %e ' 

229 % (snrat, testSNR)) 

230 

231 control = snr.magErrorFromSNR(testSNR) 

232 

233 msg = '%e is not %e; failed' % (sigma, control) 

234 

235 self.assertAlmostEqual(sigma, control, 10, msg=msg) 

236 

237 def testFWHMconversions(self): 

238 FWHMeff = 0.8 

239 FWHMgeom = snr.FWHMeff2FWHMgeom(FWHMeff) 

240 self.assertEqual(FWHMgeom, (0.822*FWHMeff+0.052)) 

241 FWHMgeom = 0.8 

242 FWHMeff = snr.FWHMgeom2FWHMeff(FWHMgeom) 

243 self.assertEqual(FWHMeff, (FWHMgeom-0.052)/0.822) 

244 

245 def testSNR_arr(self): 

246 """ 

247 Test that calcSNR_m5 works on numpy arrays of magnitudes 

248 """ 

249 rng = np.random.RandomState(17) 

250 mag_list = rng.random_sample(100)*5.0 + 15.0 

251 

252 photParams = PhotometricParameters() 

253 bp = self.bpList[0] 

254 m5 = 24.0 

255 control_list = [] 

256 for mm in mag_list: 

257 ratio, gamma = snr.calcSNR_m5(mm, bp, m5, photParams) 

258 control_list.append(ratio) 

259 control_list = np.array(control_list) 

260 

261 test_list, gamma = snr.calcSNR_m5(mag_list, bp, m5, photParams) 

262 

263 np.testing.assert_array_equal(control_list, test_list) 

264 

265 def testError_arr(self): 

266 """ 

267 Test that calcMagError_m5 works on numpy arrays of magnitudes 

268 """ 

269 rng = np.random.RandomState(17) 

270 mag_list = rng.random_sample(100)*5.0 + 15.0 

271 

272 photParams = PhotometricParameters() 

273 bp = self.bpList[0] 

274 m5 = 24.0 

275 control_list = [] 

276 for mm in mag_list: 

277 sig, gamma = snr.calcMagError_m5(mm, bp, m5, photParams) 

278 control_list.append(sig) 

279 control_list = np.array(control_list) 

280 

281 test_list, gamma = snr.calcMagError_m5(mag_list, bp, m5, photParams) 

282 

283 np.testing.assert_array_equal(control_list, test_list) 

284 

285 

286class MemoryTestClass(lsst.utils.tests.MemoryTestCase): 

287 pass 

288 

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

290 lsst.utils.tests.init() 

291 unittest.main()