Coverage for python/lsst/sims/photUtils/SedList.py : 13%

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 os
4import copy
5import numpy
6from .Bandpass import Bandpass
7from .Sed import Sed
8from lsst.sims.photUtils import getImsimFluxNorm
10__all__ = ["SedList"]
12class SedList(object):
13 """
14 This class will read in a list of Seds from disk and store them.
16 It also has the ability to renormalize, redden (according to the
17 O'Donnell 94, ApJ 422 158 dust model), and redshift the Seds.
19 As it reads in the Seds, it will keep track of each unique file it reads
20 in. If two Seds are based on the same file (before normalization, reddening,
21 etc.), it will refer back to its own memory, rather than reading the
22 file from disk a second time.
24 The method loadSedsFromList allows the user to add Seds to the list
25 after the constructor has been called.
26 """
28 def __init__(self, sedNameList, magNormList,
29 normalizingBandpass=None,
30 specMap=None,
31 fileDir = '',
32 wavelenMatch = None,
33 redshiftList = None,
34 galacticAvList = None,
35 internalAvList = None,
36 cosmologicalDimming = True):
38 """
39 @param [in] sedNameList is a list of SED file names.
41 @param [in] magNormList is a list of magnitude normalizations
42 (in the normalizingBandpass) for each of the Seds.
44 @param[in] normalizingBandpass is an instantiation of the Bandpass
45 class defining the bandpass in which the magNorms from magNormList
46 are calculated. This defaults to the Bandpass().imsimBandpass(),
47 which is essentially a delta function at 500 nm.
49 @param [in] fileDir is the base directory where the Sed files are stored
50 (defaults to current working directory).
52 @param [in] specMap is a specMap (defined in sims_utils/../fileMaps.py)
53 that maps the names in sedNameList to paths of the files relative to
54 fileDir (defaults to None; a defaultSpecMap targeted at
55 sims_sed_library is defined in sims_utils)
57 @param [in] wavelenMatch is an optional numpy array representing
58 the wavelength grid to which all Seds will be re-mapped.
60 @param [in] redshiftList is an optional list of redshifts for the Sed
62 @param [in] internalAvList is an optional list of A(V) due to internal
63 dust (for spectra of galaxies).
65 @param [in] galacticAvList is an optional list of A(V) due to
66 Milky Way Dust.
68 @param [in] cosmologicalDimming is a boolean indicating whether cosmological
69 dimming (the extray (1+z)^-1 factor in flux) should be applied to spectra
70 when they are redshifted (defaults to True)
72 Note: once wavelenMatch and cosmologicalDimming have been set in
73 the constructor, they cannot be un-set.
75 Similarly: if you construct a SedList without a galacticAvList,
76 internalAvList, or redshiftList, you cannot later add spectra with
77 whichever of those features were left out.
78 """
81 self._initialized = False
82 self._spec_map = specMap
83 self._wavelen_match = copy.deepcopy(wavelenMatch)
84 self._file_dir = fileDir
85 self._cosmological_dimming = cosmologicalDimming
87 self._normalizing_bandpass = normalizingBandpass
89 self._sed_list = []
90 self._redshift_list = None
91 self._galactic_av_list = None
92 self._internal_av_list = None
94 self._a_int = None
95 self._b_int = None
96 self._av_int_wavelen = None
98 self._a_gal = None
99 self._b_gal = None
100 self._av_gal_wavelen = None
102 self.loadSedsFromList(sedNameList, magNormList,
103 internalAvList = internalAvList,
104 galacticAvList = galacticAvList,
105 redshiftList = redshiftList)
108 def __len__(self):
109 return len(self._sed_list)
111 def __getitem__(self, index):
112 return self._sed_list[index]
114 def __iter__(self):
115 for val in self._sed_list:
116 yield val
119 # Handy routines for handling Sed/Bandpass routines with sets of dictionaries.
120 def loadSedsFromList(self, sedNameList, magNormList, \
121 internalAvList=None, galacticAvList=None, redshiftList=None):
122 """
123 Load the Seds specified by sedNameList, applying the specified normalization,
124 extinction, and redshift.
126 @param [in] sedList is a list of file names containing Seds
128 @param [in] magNorm is the magnitude normalization
130 @param [in] internalAvList is an optional list of A(V) due to internal
131 dust
133 @param [in] galacticAvList is an optional list of A(V) due to
134 Milky Way dust
136 @param [in] redshiftList is an optional list of redshifts for the
137 input Sed
139 Seds are read in and stored to this object's internal list of Seds.
141 Note: if you constructed this SedList object without internalAvList,
142 you cannot load Seds with internalAvList now. Likewise for galacticAvlist
143 and redshiftList.
144 """
146 if not self._initialized:
147 if internalAvList is not None:
148 self._internal_av_list = copy.deepcopy(list(internalAvList))
149 else:
150 self._internal_av_list = None
152 if galacticAvList is not None:
153 self._galactic_av_list = copy.deepcopy(list(galacticAvList))
154 else:
155 self._galactic_av_list = None
157 if redshiftList is not None:
158 self._redshift_list = copy.deepcopy(list(redshiftList))
159 else:
160 self._redshift_list = None
162 else:
163 if self._internal_av_list is None and internalAvList is not None:
164 raise RuntimeError("This SedList does not contain internalAvList")
165 elif self._internal_av_list is not None:
166 if internalAvList is None:
167 self._internal_av_list += [None] * len(sedNameList)
168 else:
169 self._internal_av_list += list(internalAvList)
171 if self._galactic_av_list is None and galacticAvList is not None:
172 raise RuntimeError("This SedList does not contain galacticAvList")
173 elif self._galactic_av_list is not None:
174 if galacticAvList is None:
175 self._galactic_av_list += [None] * len(sedNameList)
176 else:
177 self._galactic_av_list += list(galacticAvList)
179 if self._redshift_list is None and redshiftList is not None:
180 raise RuntimeError("This SedList does not contain redshiftList")
181 elif self._redshift_list is not None:
182 if redshiftList is None:
183 self._redshift_list += [None] * len(sedNameList)
184 else:
185 self._redshift_list += list(redshiftList)
187 temp_sed_list = []
188 for sedName, magNorm in zip(sedNameList, magNormList):
189 sed = Sed()
191 if sedName != "None":
192 if self._spec_map is not None:
193 sed.readSED_flambda(os.path.join(self._file_dir, self._spec_map[sedName]))
194 else:
195 sed.readSED_flambda(os.path.join(self._file_dir, sedName))
197 if self._normalizing_bandpass is not None:
198 fNorm = sed.calcFluxNorm(magNorm, self._normalizing_bandpass)
199 else:
200 fNorm = getImsimFluxNorm(sed, magNorm)
202 sed.multiplyFluxNorm(fNorm)
204 temp_sed_list.append(sed)
207 if internalAvList is not None:
208 self._av_int_wavelen, \
209 self._a_int, \
210 self._b_int = self.applyAv(temp_sed_list, internalAvList,
211 self._av_int_wavelen, self._a_int, self._b_int)
213 if redshiftList is not None:
214 self.applyRedshift(temp_sed_list, redshiftList)
216 if self._wavelen_match is not None:
217 for sedObj in temp_sed_list:
218 if sedObj.wavelen is not None:
219 sedObj.resampleSED(wavelen_match=self._wavelen_match)
221 if galacticAvList is not None:
222 self._av_gal_wavelen, \
223 self._a_gal, \
224 self._b_gal = self.applyAv(temp_sed_list, galacticAvList,
225 self._av_gal_wavelen, self._a_gal, self._b_gal)
227 self._sed_list += temp_sed_list
229 self._initialized = True
233 def applyAv(self, sedList, avList, dustWavelen, aCoeffs, bCoeffs):
234 """
235 Take the array of Sed objects sedList and apply extinction due to dust.
237 This method makes the necessary changes to the Seds in SedList in situ.
238 It returns the wavelength grid and corresponding dust coefficients so that
239 they an be reused on Seds with identical wavelength grids.
241 @param [in] sedList is a list of Sed objects
243 @param [in] avList is a list of Av extinction values internal to each object
245 @param [in] dustWavelen is the wavelength grid corresponding to the
246 dust model coefficients. If this differs from the wavelength grid
247 of any of the Seds in sedList, the dust model coefficients will be
248 re-generated.
250 @param [in] aCoeffs are the 'a' dust model coefficients (see O'Donnell 1994
251 ApJ 422 158)
253 @param [in] bCoeffs are the 'b' dust model coefficients from O'Donnell.
255 @param [out] dustWavelen as generated/used by this method
257 @param [out] aCoeffs as generated/used by this method
259 @param [out] bCoeffs as generated/used by this method
261 aCoeffs and bCoeffs are re-generated as needed
262 """
264 for sedobj, av in zip(sedList, avList):
265 if sedobj.wavelen is not None and av is not None:
266 #setupCCM_ab only depends on the wavelen array
267 #because this is supposed to be the same for every
268 #SED object in sedList, it is only called once for
269 #each invocation of applyAv
271 if dustWavelen is None or len(sedobj.wavelen)!=len(dustWavelen) \
272 or (sedobj.wavelen!=dustWavelen).any():
273 aCoeffs, bCoeffs = sedobj.setupCCM_ab()
274 dustWavelen = sedobj.wavelen
276 sedobj.addDust(aCoeffs, bCoeffs, A_v=av)
279 return dustWavelen, aCoeffs, bCoeffs
282 def applyRedshift(self, sedList, redshiftList):
283 """
284 Take the array of SED objects sedList and apply the arrays of extinction and redshift
285 (internalAV and redshift)
287 This method does not return anything. It makes the necessary changes
288 to the Seds in SedList in situ.
290 @param [in] sedList is a list of Sed objects
292 @param [in] redshiftList is a list of redshift values
294 This method will redshift each Sed object in sedList
295 """
297 if redshiftList is None:
298 return
300 for sedobj, redshift in zip(sedList, redshiftList):
301 if sedobj.wavelen is not None and redshift is not None:
302 sedobj.redshiftSED(redshift, dimming=self._cosmological_dimming)
303 sedobj.name = sedobj.name + '_Z' + '%.2f' %(redshift)
306 def flush(self):
307 """
308 Delete all SEDs stored in this SedList.
309 """
310 self._initialized = False
311 self._sed_list = []
312 self._internal_av_list = None
313 self._galactic_av_list = None
314 self._redshift_list = None
317 @property
318 def cosmologicalDimming(self):
319 """
320 Boolean determining whether cosmological dimming (the extra
321 (1+z)^-1 factor in flux) is applied to Seds when they are
322 redshifte by this SedList.
323 """
324 return self._cosmological_dimming
327 @property
328 def wavelenMatch(self):
329 """
330 Wavelength grid against which to match Seds stored in this
331 SedList.
332 """
333 return self._wavelen_match
336 @property
337 def redshiftList(self):
338 """
339 List of redshifts applied to the Seds stored in this
340 SedList.
341 """
342 return self._redshift_list
345 @property
346 def internalAvList(self):
347 """
348 A(V) due to internal dust applied to the Seds stored in
349 this SedList.
350 """
351 return self._internal_av_list
354 @property
355 def galacticAvList(self):
356 """
357 List of A(V) due to Milky Way dust applied to the Seds
358 stored in this SedList
359 """
360 return self._galactic_av_list