Coverage for python/lsst/sims/catUtils/IGM/applyIGM.py : 19%

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 str
3from builtins import object
4import os
5import numpy as np
6import warnings
7from lsst.sims.photUtils import Sed
8from lsst.utils import getPackageDir
10__all__ = ["ApplyIGM"]
12class ApplyIGM(object):
14 """
15 This class applies IGM to SED objects using lookup tables. If users want to enter their
16 own lookup tables they can do that by specifying self.meanLookups and self.varLookups
17 which are dictionaries containing redshift as the keys with (wavelength, transmission)
18 arrays as the values.
19 """
21 IGMisInitialized = False
22 tablesPresent = False
24 def initializeIGM(self, zMin = 1.5, zMax = 2.9, zDelta = 0.1, minWavelen = 300):
26 """
27 Initialize an applyIGM object with the desired redshift grid.
28 If lookup tables are not evenly spaced in redshift then input manually
29 desired zRange array.
31 @param [in] zMin is the minimum redshift.
33 @param [in] zMax is the maximum redshift.
35 @param [in] zDelta is the redshift spacing.
37 @param [in] minWavelen is the minimum wavelength in the lookup tables
38 """
39 self.zMin = zMin
40 self.zMax = zMax
41 self.zDelta = zDelta
42 self.minWavelen = minWavelen
43 #Don't have max wavelength since transmission goes to 1.0 at longest wavelengths
44 self.zRange = np.arange(zMin, zMax + (zDelta/2.), zDelta)
46 if self.tablesPresent == False:
47 table_dir = getPackageDir('sims_catUtils')
48 table_dir = os.path.join(table_dir,
49 'python/lsst/sims/catUtils/IGM/igm_tables')
50 self.loadTables(table_dir)
52 self.IGMisInitialized = True
55 def loadTables(self, filesDir, varianceTbl = True):
57 """
58 Read in and store in dictionary the IGM Lookup Tables that contain IGM transmission
59 for a given redshift and must be formatted in two columns:
60 (wavelength (nm), IGM Transmission %) or for variance
61 (wavelength (nm), IGM Transmission % Variance). Variance tables are not required and
62 can be turned off as a requirement. Names in directory formatted as
63 'MeanLookupTable_zSourceX.X.tbl' or 'VarLookupTable_zSourceX.X.tbl' where X.X is the redshift
64 of the given lookup table.
66 @param [in] filesDir is the location of the directory where lookup table are stored
68 @param [in] varianceTbl is a boolean that is True if variance tables are present in dir
69 for loading.
70 """
72 self.meanLookups = {}
73 self.varLookups = {}
75 for zValue in self.zRange:
76 self.meanLookups['%.1f' % zValue] = np.genfromtxt(str(filesDir + '/MeanLookupTable_zSource' +
77 '%.1f' % zValue + '.tbl.gz'))
78 if varianceTbl == True:
79 try:
80 self.varLookups['%.1f' % zValue] = np.genfromtxt(str(filesDir + '/VarLookupTable_zSource' +
81 '%.1f' % zValue + '.tbl.gz'))
82 except IOError:
83 raise IOError("Cannot find variance tables.")
85 self.tablesPresent = True
87 def applyIGM(self, redshift, sedobj):
89 """
90 Apply IGM extinction to already redshifted sed with redshift
91 between zMin and zMax defined by range of lookup tables
93 @param [in] redshift is the redshift of the incoming SED object
95 @param [in] sedobj is the SED object to which IGM extinction will be applied. This object
96 will be modified as a result of this.
97 """
99 if self.IGMisInitialized == False:
100 self.initializeIGM()
102 #First make sure redshift is in range of lookup tables.
103 if (redshift < self.zMin) or (redshift > self.zMax):
104 warnings.warn(str("IGM Lookup tables only applicable for " + str(self.zMin) + " < z < " + str(self.zMax) + ". No action taken"))
105 return
107 #Now read in closest two lookup tables for given redshift
108 lowerSed = Sed()
109 upperSed = Sed()
110 for lower, upper in zip(self.zRange[:-1], self.zRange[1:]):
111 if lower <= redshift <= upper:
112 lowerSed.setSED(self.meanLookups['%.1f' % lower][:,0],
113 flambda = self.meanLookups['%.1f' % lower][:,1])
114 upperSed.setSED(self.meanLookups['%.1f' % upper][:,0],
115 flambda = self.meanLookups['%.1f' % lower][:,1])
116 break
118 #Redshift lookup tables to redshift of source, i.e. if source redshift is 1.78 shift lookup
119 #table for 1.7 and lookup table for 1.8 to up and down to 1.78, respectively
120 zLowerShift = ((1.0 + redshift)/(1.0 + lower)) - 1.0
121 zUpperShift = ((1.0 + redshift)/(1.0 + upper)) - 1.0
122 lowerSed.redshiftSED(zLowerShift)
123 upperSed.redshiftSED(zUpperShift)
125 #Resample lower and upper transmission data onto same wavelength grid.
126 minWavelen = 300. #All lookup tables are usable above 300nm
127 maxWavelen = np.amin([lowerSed.wavelen[-1], upperSed.wavelen[-1]]) - 0.01
128 lowerSed.resampleSED(wavelen_min = minWavelen, wavelen_max = maxWavelen, wavelen_step = 0.01)
129 upperSed.resampleSED(wavelen_match = lowerSed.wavelen)
131 #Now insert this into a transmission array of 1.0 beyond the limits of current application
132 #So that we can get an sed back that extends to the longest wavelengths of the incoming sed
133 finalWavelen = np.arange(300., sedobj.wavelen[-1]+0.01, 0.01)
134 finalFlambdaExtended = np.ones(len(finalWavelen))
136 #Weighted Average of Transmission from each lookup table to get final transmission
137 #table at desired redshift
138 dzGrid = self.zDelta #Step in redshift between transmission lookup table files
139 finalSed = Sed()
140 finalFlambda = (lowerSed.flambda*(1.0 - ((redshift - lower)/dzGrid)) +
141 upperSed.flambda*(1.0 - ((upper - redshift)/dzGrid)))
142 finalFlambdaExtended[0:len(finalFlambda)] = finalFlambda
143 finalSed.setSED(wavelen = finalWavelen, flambda = finalFlambdaExtended)
145 #Resample incoming sed to new grid so that we don't get warnings from multiplySED
146 #about matching wavelength grids
147 sedobj.resampleSED(wavelen_match=finalSed.wavelen)
149 #Now multiply transmission curve by input SED to get final result and make it the new flambda
150 #data in the original sed which also is now on a new grid starting at 300 nm
151 test = sedobj.multiplySED(finalSed)
152 sedobj.flambda = test.flambda