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 object 

2import numpy as np 

3from lsst.sims.photUtils import Sed, BandpassDict 

4 

5__all__ = ["PhotometricParameters", 'Dust_values'] 

6 

7 

8class Dust_values(object): 

9 """Calculate extinction values 

10 

11 Parameters 

12 ---------- 

13 R_v : float (3.1) 

14 Extinction law parameter (3.1). 

15 bandpassDict : dict (None) 

16 A dict with keys of filtername and values of lsst.sims.photUtils.Bandpass objects. Default 

17 of None will load the standard ugrizy bandpasses. 

18 ref_ev : float (1.) 

19 The reference E(B-V) value to use. Things in MAF assume 1. 

20 """ 

21 def __init__(self, R_v=3.1, bandpassDict=None, ref_ebv=1.): 

22 # Calculate dust extinction values 

23 self.Ax1 = {} 

24 if bandpassDict is None: 

25 bandpassDict = BandpassDict.loadTotalBandpassesFromFiles(['u', 'g', 'r', 'i', 'z', 'y']) 

26 

27 for filtername in bandpassDict: 

28 wavelen_min = bandpassDict[filtername].wavelen.min() 

29 wavelen_max = bandpassDict[filtername].wavelen.max() 

30 testsed = Sed() 

31 testsed.setFlatSED(wavelen_min=wavelen_min, wavelen_max=wavelen_max, wavelen_step=1.0) 

32 self.ref_ebv = ref_ebv 

33 # Calculate non-dust-extincted magnitude 

34 flatmag = testsed.calcMag(bandpassDict[filtername]) 

35 # Add dust 

36 a, b = testsed.setupCCM_ab() 

37 testsed.addDust(a, b, ebv=self.ref_ebv, R_v=R_v) 

38 # Calculate difference due to dust when EBV=1.0 (m_dust = m_nodust - Ax, Ax > 0) 

39 self.Ax1[filtername] = testsed.calcMag(bandpassDict[filtername]) - flatmag 

40 

41 

42class DefaultPhotometricParameters(object): 

43 """ 

44 This class will just contain a bunch of dict which store 

45 the default PhotometricParameters for LSST Bandpasses 

46 

47 Users should not access this class (which is why it is 

48 not included in the __all__ declaration for this file). 

49 

50 It is only used to initialize PhotometricParameters off of 

51 a bandpass name. 

52 """ 

53 

54 # Obviously, some of these parameters (effarea, gain, platescale, 

55 # darkcurrent, and readnoise) will not change as a function of bandpass; 

56 # we are just making them dicts here to be consistent with 

57 # everything else (and to make it possible for 

58 # PhotometricParameters to access them using the bandpass name 

59 # passed to its constructor) 

60 # 

61 # Note: all dicts contain an 'any' key which will be the default 

62 # value if an unknown bandpass is asked for 

63 # 

64 # 'any' values should be kept consistent with r band 

65 

66 bandpassNames = ['u', 'g', 'r', 'i', 'z', 'y', 'any'] 

67 

68 def makeDict(value, 

69 bandpassNames = ('u', 'g', 'r', 'i', 'z', 'y', 'any')): 

70 newdict = {} 

71 for f in bandpassNames: 

72 newdict[f] = value 

73 return newdict 

74 

75 # exposure time in seconds 

76 exptimeSec = 15.0 

77 exptime = makeDict(exptimeSec) 

78 

79 # number of exposures 

80 nexpN = 2 

81 nexp = makeDict(nexpN) 

82 

83 # effective area in cm^2 

84 effareaCm2 = np.pi * (6.423/2.*100)**2 

85 effarea = makeDict(effareaCm2) 

86 

87 # electrons per ADU 

88 gainADU = 2.3 

89 gain = makeDict(gainADU) 

90 

91 # electrons per pixel per exposure 

92 readnoiseE = 8.8 

93 readnoise = makeDict(readnoiseE) 

94 

95 # electrons per pixel per second 

96 darkcurrentE = 0.2 

97 darkcurrent = makeDict(darkcurrentE) 

98 

99 # electrons per pixel per exposure 

100 othernoiseE = 0.0 

101 othernoise = makeDict(othernoiseE) 

102 

103 # arcseconds per pixel 

104 platescaleAS = 0.2 

105 platescale = makeDict(platescaleAS) 

106 

107 # systematic squared error in magnitudes 

108 # see Table 14 of the SRD document 

109 # https://docushare.lsstcorp.org/docushare/dsweb/Get/LPM-17 

110 sigmaSys = {'u':0.0075, 'g':0.005, 'r':0.005, 'i':0.005, 'z':0.0075, 'y':0.0075, 

111 'any':0.005} 

112 

113 

114class PhotometricParameters(object): 

115 

116 def __init__(self, exptime=None, 

117 nexp=None, 

118 effarea=None, 

119 gain=None, 

120 readnoise=None, 

121 darkcurrent=None, 

122 othernoise=None, 

123 platescale=None, 

124 sigmaSys=None, 

125 bandpass=None): 

126 

127 """ 

128 @param [in] exptime exposure time in seconds (defaults to LSST value) 

129 

130 @param [in] nexp number of exposures (defaults to LSST value) 

131 

132 @param [in] effarea effective area in cm^2 (defaults to LSST value) 

133 

134 @param [in] gain electrons per ADU (defaults to LSST value) 

135 

136 @param [in] readnoise electrons per pixel per exposure (defaults to LSST value) 

137 

138 @param [in] darkcurrent electons per pixel per second (defaults to LSST value) 

139 

140 @param [in] othernoise electrons per pixel per exposure (defaults to LSST value) 

141 

142 @param [in] platescale arcseconds per pixel (defaults to LSST value) 

143 

144 @param [in] sigmaSys systematic error in magnitudes 

145 (defaults to LSST value) 

146 

147 @param [in] bandpass is the name of the bandpass to which these parameters 

148 correspond. If set to an LSST bandpass, the constructor will initialize 

149 PhotometricParameters to LSST default values for that bandpass, excepting 

150 any parameters that have been set by hand, i.e 

151 

152 myPhotParams = PhotometricParameters(nexp=3, bandpass='u') 

153 

154 will initialize a PhotometricParameters object to u bandpass defaults, except 

155 with 3 exposures instead of 2. 

156 

157 If bandpass is left as None, other parameters will default to LSST r band 

158 values (except for those values set by hand). The bandpass member variable 

159 of PhotometricParameters will, however, remain None. 

160 """ 

161 

162 # readnoise, darkcurrent and othernoise are measured in electrons. 

163 # This is taken from the specifications document LSE-30 on Docushare 

164 # Section 3.4.2.3 states that the total noise per pixel shall be 12.7 electrons per visit 

165 # which the defaults sum to (remember to multply darkcurrent by the number 

166 # of seconds in an exposure=15). [9 e- per 15 second exposure] 

167 

168 self._exptime = None 

169 self._nexp = None 

170 self._effarea = None 

171 self._gain = None 

172 self._platescale = None 

173 self._sigmaSys = None 

174 self._readnoise = None 

175 self._darkcurrent = None 

176 self._othernoise = None 

177 

178 

179 self._bandpass = bandpass 

180 defaults = DefaultPhotometricParameters() 

181 

182 if bandpass is None: 

183 bandpassKey = 'any' 

184 # This is so we do not set the self._bandpass member variable 

185 # without the user's explicit consent, but we can still access 

186 # default values from the PhotometricParameterDefaults 

187 else: 

188 bandpassKey = bandpass 

189 

190 if bandpassKey in defaults.bandpassNames: 

191 self._exptime = defaults.exptime[bandpassKey] 

192 self._nexp = defaults.nexp[bandpassKey] 

193 self._effarea = defaults.effarea[bandpassKey] 

194 self._gain = defaults.gain[bandpassKey] 

195 self._platescale = defaults.platescale[bandpassKey] 

196 self._sigmaSys = defaults.sigmaSys[bandpassKey] 

197 self._readnoise = defaults.readnoise[bandpassKey] 

198 self._darkcurrent = defaults.darkcurrent[bandpassKey] 

199 self._othernoise = defaults.othernoise[bandpassKey] 

200 

201 if exptime is not None: 

202 self._exptime = exptime 

203 

204 if nexp is not None: 

205 self._nexp = nexp 

206 

207 if effarea is not None: 

208 self._effarea = effarea 

209 

210 if gain is not None: 

211 self._gain = gain 

212 

213 if platescale is not None: 

214 self._platescale = platescale 

215 

216 if sigmaSys is not None: 

217 self._sigmaSys = sigmaSys 

218 

219 if readnoise is not None: 

220 self._readnoise = readnoise 

221 

222 if darkcurrent is not None: 

223 self._darkcurrent = darkcurrent 

224 

225 if othernoise is not None: 

226 self._othernoise = othernoise 

227 

228 failureMessage = '' 

229 failureCt = 0 

230 

231 if self._exptime is None: 

232 failureMessage += 'did not set exptime\n' 

233 failureCt += 1 

234 

235 if self._nexp is None: 

236 failureMessage += 'did not set nexp\n' 

237 failureCt += 1 

238 

239 if self._effarea is None: 

240 failureMessage += 'did not set effarea\n' 

241 failureCt += 1 

242 

243 if self._gain is None: 

244 failureMessage += 'did not set gain\n' 

245 failureCt += 1 

246 

247 if self._platescale is None: 

248 failureMessage += 'did not set platescale\n' 

249 failureCt +=1 

250 

251 if self._sigmaSys is None: 

252 failureMessage += 'did not set sigmaSys\n' 

253 failureCt += 1 

254 

255 if self._readnoise is None: 

256 failureMessage += 'did not set readnoise\n' 

257 failureCt += 1 

258 

259 if self._darkcurrent is None: 

260 failureMessage += 'did not set darkcurrent\n' 

261 failureCt +=1 

262 

263 if self._othernoise is None: 

264 failureMessage += 'did not set othernoise\n' 

265 failureCt += 1 

266 

267 if failureCt>0: 

268 raise RuntimeError('In PhotometricParameters:\n%s' % failureMessage) 

269 

270 

271 

272 @property 

273 def bandpass(self): 

274 """ 

275 The name of the bandpass associated with these parameters (can be None) 

276 """ 

277 return self._bandpass 

278 

279 @bandpass.setter 

280 def bandpass(self, value): 

281 raise RuntimeError("You should not be setting bandpass on the fly; " + 

282 "Just instantiate a new case of PhotometricParameters") 

283 

284 @property 

285 def exptime(self): 

286 """ 

287 exposure time in seconds 

288 """ 

289 return self._exptime 

290 

291 @exptime.setter 

292 def exptime(self, value): 

293 raise RuntimeError("You should not be setting exptime on the fly; " + 

294 "Just instantiate a new case of PhotometricParameters") 

295 

296 

297 @property 

298 def nexp(self): 

299 """ 

300 number of exposures 

301 """ 

302 return self._nexp 

303 

304 @nexp.setter 

305 def nexp(self, value): 

306 raise RuntimeError("You should not be setting nexp on the fly; " + 

307 "Just instantiate a new case of PhotometricParameters") 

308 

309 

310 @property 

311 def effarea(self): 

312 """ 

313 effective area in cm^2 

314 """ 

315 return self._effarea 

316 

317 @effarea.setter 

318 def effarea(self, value): 

319 raise RuntimeError("You should not be setting effarea on the fly; " + 

320 "Just instantiate a new case of PhotometricParameters") 

321 

322 

323 @property 

324 def gain(self): 

325 """ 

326 electrons per ADU 

327 """ 

328 return self._gain 

329 

330 @gain.setter 

331 def gain(self, value): 

332 raise RuntimeError("You should not be setting gain on the fly; " + 

333 "Just instantiate a new case of PhotometricParameters") 

334 

335 

336 @property 

337 def platescale(self): 

338 """ 

339 arcseconds per pixel 

340 """ 

341 return self._platescale 

342 

343 @platescale.setter 

344 def platescale(self, value): 

345 raise RuntimeError("You should not be setting platescale on the fly; " + 

346 "Just instantiate a new case of PhotometricParameters") 

347 

348 

349 @property 

350 def readnoise(self): 

351 """ 

352 electrons per pixel per exposure 

353 """ 

354 return self._readnoise 

355 

356 @readnoise.setter 

357 def readnoise(self, value): 

358 raise RuntimeError("You should not be setting readnoise on the fly; " + 

359 "Just instantiate a new case of PhotometricParameters") 

360 

361 

362 @property 

363 def darkcurrent(self): 

364 """ 

365 electrons per pixel per second 

366 """ 

367 return self._darkcurrent 

368 

369 @darkcurrent.setter 

370 def darkcurrent(self, value): 

371 raise RuntimeError("You should not be setting darkcurrent on the fly; " + 

372 "Just instantiate a new case of PhotometricParameters") 

373 

374 

375 @property 

376 def othernoise(self): 

377 """ 

378 electrons per pixel per exposure 

379 """ 

380 return self._othernoise 

381 

382 @othernoise.setter 

383 def othernoise(self,value): 

384 raise RuntimeError("You should not be setting othernoise on the fly; " + 

385 "Just instantiate a new case of PhotometricParameters") 

386 

387 

388 @property 

389 def sigmaSys(self): 

390 """ 

391 systematic error in magnitudes 

392 """ 

393 return self._sigmaSys 

394 

395 

396 @sigmaSys.setter 

397 def sigmaSys(self, value): 

398 raise RuntimeError("You should not be setting sigmaSys on the fly; " + 

399 "Just instantiate a new case of PhotometricParameters")