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 object 

3import copy 

4import numpy 

5import os 

6from lsst.utils import getPackageDir 

7from collections import OrderedDict 

8from .Bandpass import Bandpass 

9from .Sed import Sed 

10 

11__all__ = ["BandpassDict"] 

12 

13class BandpassDict(object): 

14 """ 

15 This class will wrap an OrderedDict of Bandpass instantiations. 

16 

17 Upon instantiation, this class's constructor will resample 

18 the input Bandpasses to be on the same wavelength grid (defined 

19 by the first input Bandpass). The constructor will then calculate 

20 the 2-D phiArray for quick calculation of magnitudes in all 

21 Bandpasses simultaneously (see the member methods magListForSed, 

22 magListForSedList, fluxListForSed, fluxListForSedList). 

23 

24 Note: when re-sampling the wavelength grid, it is assumed that 

25 the first bandpass is sampled on a uniform grid (i.e. all bandpasses 

26 are resampled to a grid with wavlen_min, wavelen_max determined by 

27 the bounds of the first bandpasses grid and with wavelen_step defined 

28 to be the difference between the 0th and 1st element of the first 

29 bandpass' wavelength grid). 

30 

31 The class methods loadBandpassesFromFiles and loadTotalBandpassesFromFiles 

32 can be used to easily read throughput files in from disk and conver them 

33 into BandpassDict objects. 

34 """ 

35 

36 def __init__(self, bandpassList, bandpassNameList): 

37 """ 

38 @param [in] bandpassList is a list of Bandpass instantiations 

39 

40 @param [in] bandpassNameList is a list of tags to be associated 

41 with those Bandpasses. These will be used as keys for the BandpassDict. 

42 """ 

43 self._bandpassDict = OrderedDict() 

44 self._wavelen_match = None 

45 for bandpassName, bandpass in zip(bandpassNameList, bandpassList): 

46 

47 if bandpassName in self._bandpassDict: 

48 raise RuntimeError("The bandpass %s occurs twice in your input " % bandpassName \ 

49 + "to BandpassDict") 

50 

51 self._bandpassDict[bandpassName] = copy.deepcopy(bandpass) 

52 if self._wavelen_match is None: 

53 self._wavelen_match = self._bandpassDict[bandpassName].wavelen 

54 

55 dummySed = Sed() 

56 self._phiArray, self._wavelenStep = dummySed.setupPhiArray(list(self._bandpassDict.values())) 

57 

58 

59 def __getitem__(self, bandpass): 

60 return self._bandpassDict[bandpass] 

61 

62 

63 def __len__(self): 

64 return len(self._bandpassDict) 

65 

66 

67 def __iter__(self): 

68 for val in self._bandpassDict: 

69 yield val 

70 

71 

72 def values(self): 

73 """ 

74 Returns a list of the BandpassDict's values. 

75 """ 

76 return list(self._bandpassDict.values()) 

77 

78 

79 def keys(self): 

80 """ 

81 Returns a list of the BandpassDict's keys. 

82 """ 

83 return list(self._bandpassDict.keys()) 

84 

85 

86 @classmethod 

87 def loadBandpassesFromFiles(cls, 

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

89 filedir = os.path.join(getPackageDir('throughputs'), 'baseline'), 

90 bandpassRoot = 'filter_', 

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

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

93 atmoTransmission=os.path.join(getPackageDir('throughputs'), 

94 'baseline','atmos_std.dat')): 

95 """ 

96 Load bandpass information from files into BandpassDicts. 

97 This method will separate the bandpasses into contributions due to instrumentations 

98 and contributions due to the atmosphere. 

99 

100 @param [in] bandpassNames is a list of strings labeling the bandpasses 

101 (e.g. ['u', 'g', 'r', 'i', 'z', 'y']) 

102 

103 @param [in] filedir is a string indicating the name of the directory containing the 

104 bandpass files 

105 

106 @param [in] bandpassRoot is the root of the names of the files associated with the 

107 bandpasses. This method assumes that bandpasses are stored in 

108 filedir/bandpassRoot_bandpassNames[i].dat 

109 

110 @param [in] componentList lists the files associated with bandpasses representing 

111 hardware components shared by all filters 

112 (defaults to ['detector.dat', 'm1.dat', 'm2.dat', 'm3.dat', 'lens1.dat', 

113 'lense2.dat', 'lenst3.dat'] 

114 for LSST). These files are also expected to be stored in filedir 

115 

116 @param [in] atmoTransmission is the absolute path to the file representing the 

117 transmissivity of the atmosphere (defaults to baseline/atmos_std.dat in the LSST 

118 'throughputs' package). 

119 

120 @param [out] bandpassDict is a BandpassDict containing the total 

121 throughput (instrumentation + atmosphere) 

122 

123 @param [out] hardwareBandpassDict is a BandpassDict containing 

124 the throughput due to instrumentation only 

125 """ 

126 

127 commonComponents = [] 

128 for cc in componentList: 

129 commonComponents.append(os.path.join(filedir,cc)) 

130 

131 bandpassList = [] 

132 hardwareBandpassList = [] 

133 

134 for w in bandpassNames: 

135 components = commonComponents + [os.path.join(filedir,"%s.dat" % (bandpassRoot +w))] 

136 bandpassDummy = Bandpass() 

137 bandpassDummy.readThroughputList(components) 

138 hardwareBandpassList.append(bandpassDummy) 

139 

140 components += [atmoTransmission] 

141 bandpassDummy = Bandpass() 

142 bandpassDummy.readThroughputList(components) 

143 bandpassList.append(bandpassDummy) 

144 

145 

146 bandpassDict = cls(bandpassList, bandpassNames) 

147 hardwareBandpassDict = cls(hardwareBandpassList, bandpassNames) 

148 

149 return bandpassDict, hardwareBandpassDict 

150 

151 

152 @classmethod 

153 def loadTotalBandpassesFromFiles(cls, 

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

155 bandpassDir = os.path.join(getPackageDir('throughputs'),'baseline'), 

156 bandpassRoot = 'total_'): 

157 """ 

158 This will take the list of band passes named by bandpassNames and load them into 

159 a BandpassDict 

160 

161 The bandpasses loaded this way are total bandpasses: they account for instrumental 

162 and atmospheric transmission. 

163 

164 @param [in] bandpassNames is a list of names identifying each filter. 

165 Defaults to ['u', 'g', 'r', 'i', 'z', 'y'] 

166 

167 @param [in] bandpassDir is the name of the directory where the bandpass files are stored 

168 

169 @param [in] bandpassRoot contains the first part of the bandpass file name, i.e., it is assumed 

170 that the bandpasses are stored in files of the type 

171 

172 bandpassDir/bandpassRoot_bandpassNames[i].dat 

173 

174 if we want to load bandpasses for a telescope other than LSST, we would do so 

175 by altering bandpassDir and bandpassRoot 

176 

177 @param [out] bandpassDict is a BandpassDict containing the loaded throughputs 

178 """ 

179 

180 bandpassList = [] 

181 

182 for w in bandpassNames: 

183 bandpassDummy = Bandpass() 

184 bandpassDummy.readThroughput(os.path.join(bandpassDir,"%s.dat" % (bandpassRoot + w))) 

185 bandpassList.append(bandpassDummy) 

186 

187 return cls(bandpassList, bandpassNames) 

188 

189 

190 def _magListForSed(self, sedobj, indices=None): 

191 """ 

192 This is a private method which will take an sedobj which has already 

193 been resampled to self._wavelen_match and calculate the magnitudes 

194 of that object in each of the bandpasses stored in this Dict. 

195 

196 The results are returned as a list. 

197 """ 

198 

199 if sedobj.wavelen is None: 

200 return [numpy.NaN]*len(self._bandpassDict) 

201 else: 

202 

203 #for some reason, moving this call to flambdaTofnu() 

204 #to a point earlier in the 

205 #process results in some SEDs having 'None' for fnu. 

206 # 

207 #I looked more carefully at the documentation in Sed.py 

208 #Any time you update flambda in any way, fnu gets set to 'None' 

209 #This is to prevent the two arrays from getting out synch 

210 #(e.g. renormalizing flambda but forgettint to renormalize fnu) 

211 # 

212 sedobj.flambdaTofnu() 

213 

214 if indices is not None: 

215 outputList = [numpy.NaN] * len(self._bandpassDict) 

216 magList = sedobj.manyMagCalc(self._phiArray, self._wavelenStep, observedBandpassInd=indices) 

217 for i, ix in enumerate(indices): 

218 outputList[ix] = magList[i] 

219 else: 

220 outputList = sedobj.manyMagCalc(self._phiArray, self._wavelenStep) 

221 

222 return outputList 

223 

224 

225 def magListForSed(self, sedobj, indices=None): 

226 """ 

227 Return a list of magnitudes for a single Sed object. 

228 

229 @param [in] sedobj is an Sed object. Its wavelength grid can be arbitrary. If necessary, 

230 a copy will be created and resampled onto the wavelength grid of the Bandpasses before 

231 magnitudes are calculated. The original Sed will be unchanged. 

232 

233 @param [in] indices is an optional list of indices indicating which bandpasses to actually 

234 calculate magnitudes for. Other magnitudes will be listed as numpy.NaN (i.e. this method will 

235 return as many magnitudes as were loaded with the loadBandpassesFromFiles methods; it will 

236 just return numpy.NaN for magnitudes you did not actually ask for) 

237 

238 @param [out] magList is a list of magnitudes in the bandpasses stored in this BandpassDict 

239 """ 

240 

241 if sedobj.wavelen is not None: 

242 

243 # If the Sed's wavelength grid agrees with self._wavelen_match to one part in 

244 # 10^6, just use the Sed as-is. Otherwise, copy it and resample it onto 

245 # self._wavelen_match 

246 if sedobj._needResample(wavelen_match=self._wavelen_match): 

247 dummySed = Sed(wavelen=sedobj.wavelen, flambda=sedobj.flambda) 

248 dummySed.resampleSED(force=True, wavelen_match=self._wavelen_match) 

249 else: 

250 dummySed = sedobj 

251 

252 return numpy.array(self._magListForSed(dummySed, indices=indices)) 

253 

254 else: 

255 return numpy.array([numpy.NaN]*len(self._bandpassDict)) 

256 

257 

258 def magDictForSed(self, sedobj, indices=None): 

259 """ 

260 Return an OrderedDict of magnitudes for a single Sed object. 

261 

262 The OrderedDict will be keyed off of the keys to this BandpassDict 

263 

264 @param [in] sedobj is an Sed object. Its wavelength grid can be arbitrary. If necessary, 

265 a copy will be created and resampled onto the wavelength grid of the Bandpasses before 

266 magnitudes are calculated. The original Sed will be unchanged. 

267 

268 @param [in] indices is an optional list of indices indicating which bandpasses to actually 

269 calculate magnitudes for. Other magnitudes will be listed as numpy.NaN (i.e. this method will 

270 return as many magnitudes as were loaded with the loadBandpassesFromFiles methods; it will 

271 just return numpy.NaN for magnitudes you did not actually ask for) 

272 

273 @param [out] magDict is an OrderedDict of magnitudes in the bandpasses stored in this BandpassDict 

274 """ 

275 

276 magList = self.magListForSed(sedobj, indices=indices) 

277 

278 outputDict = OrderedDict() 

279 

280 for ix, bp in enumerate(self._bandpassDict.keys()): 

281 outputDict[bp] = magList[ix] 

282 

283 return outputDict 

284 

285 

286 def magListForSedList(self, sedList, indices=None): 

287 """ 

288 Return a 2-D array of magnitudes from a SedList. 

289 Each row will correspond to a different Sed, each column 

290 will correspond to a different bandpass, i.e. in the case of 

291 

292 mag = myBandpassDict.magListForSedList(mySedList) 

293 

294 mag[0][0] will be the magnitude of the 0th Sed in the 0th bandpass 

295 mag[0][1] will be the magnitude of the 0th Sed in the 1st bandpass 

296 mag[1][1] will be the magnitude of the 1st Sed in the 1st bandpass 

297 etc. 

298 

299 For maximum efficiency, use the wavelenMatch keyword when loading 

300 SEDs into your SedList and make sure that wavelenMatch = myBandpassDict.wavelenMatch. 

301 That way, this method will not have to waste time resampling the Seds 

302 onto the wavelength grid of the BandpassDict. 

303 

304 @param [in] sedList is a SedList containing the Seds 

305 whose magnitudes are desired. 

306 

307 @param [in] indices is an optional list of indices indicating which bandpasses to actually 

308 calculate magnitudes for. Other magnitudes will be listed as numpy.NaN (i.e. this method will 

309 return as many magnitudes as were loaded with the loadBandpassesFromFiles methods; it will 

310 just return numpy.NaN for magnitudes you did not actually ask for) 

311 

312 @param [out] output_list is a 2-D numpy array containing the magnitudes 

313 of each Sed (the rows) in each bandpass contained in this BandpassDict 

314 (the columns) 

315 """ 

316 

317 one_at_a_time = False 

318 if sedList.wavelenMatch is None: 

319 one_at_a_time = True 

320 elif sedList[0]._needResample(wavelen_match=self._wavelen_match): 

321 one_at_a_time = True 

322 

323 output_list = [] 

324 if one_at_a_time: 

325 for sed_obj in sedList: 

326 sub_list = self.magListForSed(sed_obj, indices=indices) 

327 output_list.append(sub_list) 

328 else: 

329 # the difference between this block and the block above is that the block 

330 # above performs the additional check of making sure that sed_obj.wavelen 

331 # is equivalent to self._wavelen_match 

332 for sed_obj in sedList: 

333 sub_list = self._magListForSed(sed_obj, indices=indices) 

334 output_list.append(sub_list) 

335 

336 return numpy.array(output_list) 

337 

338 

339 def magArrayForSedList(self, sedList, indices=None): 

340 """ 

341 Return a dtyped numpy array of magnitudes from a SedList. 

342 The array will be keyed to the keys of this BandpassDict, 

343 i.e. in the case of 

344 

345 mag = myBandpassDict.magArrayForSedList(mySedList) 

346 

347 mag['u'][0] will be the magnitude of the 0th Sed in the 'u' bandpass 

348 mag['u'][1] will be the magnitude of the 1st Sed in the 'u' bandpass 

349 mag['z'] will be a numpy array of every Sed's magnitude in the 'z' bandpass 

350 etc. 

351 

352 For maximum efficiency, use the wavelenMatch keyword when loading 

353 SEDs into your SedList and make sure that wavelenMatch = myBandpassDict.wavelenMatch. 

354 That way, this method will not have to waste time resampling the Seds 

355 onto the wavelength grid of the BandpassDict. 

356 

357 @param [in] sedList is a SedList containing the Seds 

358 whose magnitudes are desired. 

359 

360 @param [in] indices is an optional list of indices indicating which bandpasses to actually 

361 calculate magnitudes for. Other magnitudes will be listed as numpy.NaN (i.e. this method will 

362 return as many magnitudes as were loaded with the loadBandpassesFromFiles methods; it will 

363 just return numpy.NaN for magnitudes you did not actually ask for) 

364 

365 @param [out] output_array is a dtyped numpy array of magnitudes (see above). 

366 """ 

367 

368 magList = self.magListForSedList(sedList, indices=indices) 

369 

370 dtype = numpy.dtype([(bp, numpy.float) for bp in self._bandpassDict.keys()]) 

371 

372 outputArray = numpy.array([tuple(row) for row in magList], dtype=dtype) 

373 

374 return outputArray 

375 

376 

377 def _fluxListForSed(self, sedobj, indices=None): 

378 """ 

379 This is a private method which will take an sedobj which has already 

380 been resampled to self._wavelen_match and calculate the fluxes 

381 of that object in each of the bandpasses stored in this Dict. 

382 

383 The results are returned as a list. 

384 """ 

385 

386 if sedobj.wavelen is None: 

387 return [numpy.NaN]*len(self._bandpassDict) 

388 else: 

389 

390 #for some reason, moving this call to flambdaTofnu() 

391 #to a point earlier in the 

392 #process results in some SEDs having 'None' for fnu. 

393 # 

394 #I looked more carefully at the documentation in Sed.py 

395 #Any time you update flambda in any way, fnu gets set to 'None' 

396 #This is to prevent the two arrays from getting out synch 

397 #(e.g. renormalizing flambda but forgettint to renormalize fnu) 

398 # 

399 sedobj.flambdaTofnu() 

400 

401 if indices is not None: 

402 outputList = [numpy.NaN] * len(self._bandpassDict) 

403 magList = sedobj.manyFluxCalc(self._phiArray, self._wavelenStep, observedBandpassInd=indices) 

404 for i, ix in enumerate(indices): 

405 outputList[ix] = magList[i] 

406 else: 

407 outputList = sedobj.manyFluxCalc(self._phiArray, self._wavelenStep) 

408 

409 return outputList 

410 

411 

412 def fluxListForSed(self, sedobj, indices=None): 

413 """ 

414 Return a list of Fluxes for a single Sed object. 

415 

416 @param [in] sedobj is an Sed object. Its wavelength grid can be arbitrary. If necessary, 

417 a copy will be created and resampled onto the wavelength grid of the Bandpasses before 

418 fluxes are calculated. The original Sed will be unchanged. 

419 

420 @param [in] indices is an optional list of indices indicating which bandpasses to actually 

421 calculate fluxes for. Other fluxes will be listed as numpy.NaN (i.e. this method will 

422 return as many fluxes as were loaded with the loadBandpassesFromFiles methods; it will 

423 just return numpy.NaN for fluxes you did not actually ask for) 

424 

425 @param [out] fluxList is a list of fluxes in the bandpasses stored in this BandpassDict 

426 

427 Note on units: Fluxes calculated this way will be the flux density integrated over the 

428 weighted response curve of the bandpass. See equaiton 2.1 of the LSST Science Book 

429 

430 http://www.lsst.org/scientists/scibook 

431 """ 

432 

433 if sedobj.wavelen is not None: 

434 

435 # If the Sed's wavelength grid agrees with self._wavelen_match to one part in 

436 # 10^6, just use the Sed as-is. Otherwise, copy it and resample it onto 

437 # self._wavelen_match 

438 if sedobj._needResample(wavelen_match=self._wavelen_match): 

439 dummySed = Sed(wavelen=sedobj.wavelen, flambda=sedobj.flambda) 

440 dummySed.resampleSED(force=True, wavelen_match=self._wavelen_match) 

441 else: 

442 dummySed = sedobj 

443 

444 return numpy.array(self._fluxListForSed(dummySed, indices=indices)) 

445 

446 else: 

447 return numpy.array([numpy.NaN]*len(self._bandpassDict)) 

448 

449 

450 def fluxDictForSed(self, sedobj, indices=None): 

451 """ 

452 Return an OrderedDict of fluxes for a single Sed object. 

453 

454 The OrderedDict will be keyed off of the keys for this BandpassDict 

455 

456 @param [in] sedobj is an Sed object. Its wavelength grid can be arbitrary. If necessary, 

457 a copy will be created and resampled onto the wavelength grid of the Bandpasses before 

458 fluxes are calculated. The original Sed will be unchanged. 

459 

460 @param [in] indices is an optional list of indices indicating which bandpasses to actually 

461 calculate fluxes for. Other fluxes will be listed as numpy.NaN (i.e. this method will 

462 return as many fluxes as were loaded with the loadBandpassesFromFiles methods; it will 

463 just return numpy.NaN for fluxes you did not actually ask for) 

464 

465 @param [out] fluxList is a list of fluxes in the bandpasses stored in this BandpassDict 

466 

467 Note on units: Fluxes calculated this way will be the flux density integrated over the 

468 weighted response curve of the bandpass. See equaiton 2.1 of the LSST Science Book 

469 

470 http://www.lsst.org/scientists/scibook 

471 """ 

472 fluxList = self.fluxListForSed(sedobj, indices=indices) 

473 

474 outputDict = OrderedDict() 

475 

476 for ix, bp in enumerate(self._bandpassDict.keys()): 

477 outputDict[bp] = fluxList[ix] 

478 

479 return outputDict 

480 

481 

482 def fluxListForSedList(self, sedList, indices=None): 

483 """ 

484 Return a 2-D array of fluxes from a SedList. 

485 Each row will correspond to a different Sed, each column 

486 will correspond to a different bandpass, i.e. in the case of 

487 

488 flux = myBandpassDict.fluxListForSedList(mySedList) 

489 

490 flux[0][0] will be the flux of the 0th Sed in the 0th bandpass 

491 flux[0][1] will be the flux of the 0th Sed in the 1st bandpass 

492 flux[1][1] will be the flux of the 1st Sed in the 1st bandpass 

493 etc. 

494 

495 For maximum efficiency, use the wavelenMatch keyword when loading 

496 SEDs into your SedList and make sure that wavelenMatch = myBandpassDict.wavelenMatch. 

497 That way, this method will not have to waste time resampling the Seds 

498 onto the wavelength grid of the BandpassDict. 

499 

500 @param [in] sedList is a SedList containing the Seds 

501 whose fluxes are desired. 

502 

503 @param [in] indices is an optional list of indices indicating which bandpasses to actually 

504 calculate fluxes for. Other fluxes will be listed as numpy.NaN (i.e. this method will 

505 return as many fluxes as were loaded with the loadBandpassesFromFiles methods; it will 

506 just return numpy.NaN for fluxes you did not actually ask for) 

507 

508 @param [out] output_list is a 2-D numpy array containing the fluxes 

509 of each Sed (the rows) in each bandpass contained in this BandpassDict 

510 (the columns) 

511 

512 Note on units: Fluxes calculated this way will be the flux density integrated over the 

513 weighted response curve of the bandpass. See equaiton 2.1 of the LSST Science Book 

514 

515 http://www.lsst.org/scientists/scibook 

516 """ 

517 

518 one_at_a_time = False 

519 if sedList.wavelenMatch is None: 

520 one_at_a_time = True 

521 elif sedList[0]._needResample(wavelen_match=self._wavelen_match): 

522 one_at_a_time = True 

523 

524 output_list = [] 

525 if one_at_a_time: 

526 for sed_obj in sedList: 

527 sub_list = self.fluxListForSed(sed_obj, indices=indices) 

528 output_list.append(sub_list) 

529 else: 

530 # the difference between this block and the block above is that the block 

531 # above performs the additional check of making sure that sed_obj.wavelen 

532 # is equivalent to self._wavelen_match 

533 for sed_obj in sedList: 

534 sub_list = self._fluxListForSed(sed_obj, indices=indices) 

535 output_list.append(sub_list) 

536 

537 return numpy.array(output_list) 

538 

539 

540 def fluxArrayForSedList(self, sedList, indices=None): 

541 """ 

542 Return a dtyped numpy array of fluxes from a SedList. 

543 The array will be keyed to the keys of this BandpassDict, 

544 i.e. in the case of 

545 

546 flux = myBandpassDict.fluxArrayForSedList(mySedList) 

547 

548 flux['u'][0] will be the flux of the 0th Sed in the 'u' bandpass 

549 flux['u'][1] will be the flux of the 1st Sed in the 'u' bandpass 

550 flux['z'] will be a numpy array of every Sed's flux in the 'z' bandpass 

551 etc. 

552 

553 For maximum efficiency, use the wavelenMatch keyword when loading 

554 SEDs into your SedList and make sure that wavelenMatch = myBandpassDict.wavelenMatch. 

555 That way, this method will not have to waste time resampling the Seds 

556 onto the wavelength grid of the BandpassDict. 

557 

558 @param [in] sedList is a SedList containing the Seds 

559 whose fluxes are desired. 

560 

561 @param [in] indices is an optional list of indices indicating which bandpasses to actually 

562 calculate fluxes for. Other fluxes will be listed as numpy.NaN (i.e. this method will 

563 return as many fluxes as were loaded with the loadBandpassesFromFiles methods; it will 

564 just return numpy.NaN for fluxes you did not actually ask for) 

565 

566 @param [out] output_list is a 2-D numpy array containing the fluxes 

567 of each Sed (the rows) in each bandpass contained in this BandpassDict 

568 (the columns) 

569 

570 Note on units: Fluxes calculated this way will be the flux density integrated over the 

571 weighted response curve of the bandpass. See equaiton 2.1 of the LSST Science Book 

572 

573 http://www.lsst.org/scientists/scibook 

574 """ 

575 

576 fluxList = self.fluxListForSedList(sedList, indices=indices) 

577 

578 dtype = numpy.dtype([(bp, numpy.float) for bp in self._bandpassDict.keys()]) 

579 

580 outputArray = numpy.array([tuple(row) for row in fluxList], dtype=dtype) 

581 

582 return outputArray 

583 

584 

585 @property 

586 def phiArray(self): 

587 """ 

588 A 2-D numpy array storing the values of phi (see eqn 2.3 of the science 

589 book) for all of the bandpasses in this dict. 

590 """ 

591 return self._phiArray 

592 

593 

594 @property 

595 def wavelenStep(self): 

596 """ 

597 The step size of the wavelength grid for all of the bandpasses 

598 stored in this dict. 

599 """ 

600 return self._wavelenStep 

601 

602 

603 @property 

604 def wavelenMatch(self): 

605 """ 

606 The wavelength grid (in nm) on which all of the bandpass 

607 throughputs have been sampled. 

608 """ 

609 return self._wavelen_match