Example #1
0
def calcEffWavelen(hardware, title, throughputDir=None):
    photParams = PhotometricParameters()
    lsstDefaults = LSSTdefaults()
    atmos = {}
    stdAtmoFile = os.path.join(os.getenv('SYSENG_THROUGHPUTS_DIR'),
                               'siteProperties/pachonModtranAtm_12.dat')
    atmos['std'] = Bandpass()
    atmos['std'].readThroughput(stdAtmoFile)
    multiAtmos = False
    if throughputDir is None:
        throughputDir = os.getenv('THROUGHPUTS_DIR')
    if throughputDir is not None:
        multiAtmos = True
        Xarr = np.arange(1.0, 2.55, 0.1)
        for X in Xarr:
            atmos['%.1f' % X] = Bandpass()
            atmos['%.1f' % X].readThroughput(
                os.path.join(throughputDir,
                             'atmos/atmos_%d.dat' % (int(X * 10))))

    atmoskeys = sorted(atmos.keys())
    print title
    print '    %s' % ('    '.join(atmoskeys))
    system = Bandpass()
    effsb = {}
    for f in ['u', 'g', 'r', 'i', 'z', 'y']:
        writestring = '%s ' % f
        for k in atmoskeys:
            system.wavelen, system.sb = hardware[f].multiplyThroughputs(
                atmos[k].wavelen, atmos[k].sb)
            effphi, effsb[k] = system.calcEffWavelen()
            writestring += '%.2f ' % (effsb[k])
        print writestring
def calcEffWavelen(hardware, title, throughputDir=None):
    photParams = PhotometricParameters()
    lsstDefaults = LSSTdefaults()
    atmos = {}
    stdAtmoFile = os.path.join(os.getenv('SYSENG_THROUGHPUTS_DIR'), 'siteProperties/pachonModtranAtm_12.dat')
    atmos['std'] = Bandpass()
    atmos['std'].readThroughput(stdAtmoFile)
    multiAtmos = False
    if throughputDir is None:
        throughputDir = os.getenv('THROUGHPUTS_DIR')
    if throughputDir is not None:
        multiAtmos = True
        Xarr = np.arange(1.0, 2.55, 0.1)
        for X in Xarr:
            atmos['%.1f' %X] = Bandpass()
            atmos['%.1f' %X].readThroughput(os.path.join(throughputDir,
                                                         'atmos/atmos_%d.dat' %(int(X*10))))

    atmoskeys = sorted(atmos.keys())
    print title
    print '    %s' %('    '.join(atmoskeys))
    system = Bandpass()
    effsb = {}
    for f in ['u', 'g', 'r', 'i', 'z', 'y']:
        writestring = '%s ' %f
        for k in atmoskeys:
            system.wavelen, system.sb = hardware[f].multiplyThroughputs(atmos[k].wavelen, atmos[k].sb)
            effphi, effsb[k] = system.calcEffWavelen()
            writestring += '%.2f ' %(effsb[k])
        print writestring
Example #3
0
    def __init__(self, mags=False, darkSkyMags=None, fitResults=None):
        """
        Read the Solar spectrum into a handy object and compute mags in different filters
        mags:  If true, only return the LSST filter magnitudes, otherwise return the full spectrum

        darkSkyMags = dict of the zenith dark sky values to be assumed. The twilight fits are
        done relative to the dark sky level.
        fitResults = dict of twilight parameters based on twilightFunc. Keys should be filter names.
        """

        if darkSkyMags is None:
            darkSkyMags = {
                'u': 22.8,
                'g': 22.3,
                'r': 21.2,
                'i': 20.3,
                'z': 19.3,
                'y': 18.0,
                'B': 22.35,
                'G': 21.71,
                'R': 21.3
            }

        self.mags = mags

        dataDir = getPackageDir('sims_skybrightness_data')

        solarSaved = np.load(os.path.join(dataDir, 'solarSpec/solarSpec.npz'))
        self.solarSpec = Sed(wavelen=solarSaved['wave'],
                             flambda=solarSaved['spec'])
        solarSaved.close()

        canonFilters = {}
        fnames = ['blue_canon.csv', 'green_canon.csv', 'red_canon.csv']

        # Filter names, from bluest to reddest.
        self.filterNames = ['B', 'G', 'R']

        for fname, filterName in zip(fnames, self.filterNames):
            bpdata = np.genfromtxt(os.path.join(dataDir, 'Canon/', fname),
                                   delimiter=', ',
                                   dtype=list(
                                       zip(['wave', 'through'], [float] * 2)))
            bpTemp = Bandpass()
            bpTemp.setBandpass(bpdata['wave'], bpdata['through'])
            canonFilters[filterName] = bpTemp

        # Tack on the LSST filters
        throughPath = os.path.join(getPackageDir('throughputs'), 'baseline')
        lsstKeys = ['u', 'g', 'r', 'i', 'z', 'y']
        for key in lsstKeys:
            bp = np.loadtxt(os.path.join(throughPath,
                                         'filter_' + key + '.dat'),
                            dtype=list(zip(['wave', 'trans'], [float] * 2)))
            tempB = Bandpass()
            tempB.setBandpass(bp['wave'], bp['trans'])
            canonFilters[key] = tempB
            self.filterNames.append(key)

        # MAGIC NUMBERS from fitting the all-sky camera:
        # Code to generate values in sims_skybrightness/examples/fitTwiSlopesSimul.py
        # Which in turn uses twilight maps from sims_skybrightness/examples/buildTwilMaps.py
        # values are of the form:
        # 0: ratio of f^z_12 to f_dark^z
        # 1: slope of curve wrt sun alt
        # 2: airmass term (10^(arg[2]*(X-1)))
        # 3: azimuth term.
        # 4: zenith dark sky flux (erg/s/cm^2)

        # For z and y, just assuming the shape parameter fits are similar to the other bands.
        # Looks like the diode is not sensitive enough to detect faint sky.
        # Using the Patat et al 2006 I-band values for z and modeified a little for y as a temp fix.
        if fitResults is None:
            self.fitResults = {
                'B': [
                    7.56765633e+00, 2.29798055e+01, 2.86879956e-01,
                    3.01162143e-01, 2.58462036e-04
                ],
                'G': [
                    2.38561156e+00, 2.29310648e+01, 2.97733083e-01,
                    3.16403197e-01, 7.29660095e-04
                ],
                'R': [
                    1.75498017e+00, 2.22011802e+01, 2.98619033e-01,
                    3.28880254e-01, 3.24411056e-04
                ],
                'z': [2.29, 24.08, 0.3, 0.3, -666],
                'y': [2.0, 24.08, 0.3, 0.3, -666]
            }

            # XXX-completely arbitrary fudge factor to make things brighter in the blue
            # Just copy the blue and say it's brighter.
            self.fitResults['u'] = [
                16., 2.29622121e+01, 2.85862729e-01, 2.99902574e-01,
                2.32325117e-04
            ]
        else:
            self.fitResults = fitResults

        # Take out any filters that don't have fit results
        self.filterNames = [
            key for key in self.filterNames if key in self.fitResults
        ]

        self.effWave = []
        self.solarMag = []
        for filterName in self.filterNames:
            self.effWave.append(canonFilters[filterName].calcEffWavelen()[0])
            self.solarMag.append(
                self.solarSpec.calcMag(canonFilters[filterName]))

        ord = np.argsort(self.effWave)
        self.filterNames = np.array(self.filterNames)[ord]
        self.effWave = np.array(self.effWave)[ord]
        self.solarMag = np.array(self.solarMag)[ord]

        # update the fit results to be zeropointed properly
        for key in self.fitResults:
            f0 = 10.**(-0.4 * (darkSkyMags[key] - np.log10(3631.)))
            self.fitResults[key][-1] = f0

        self.solarWave = self.solarSpec.wavelen
        self.solarFlux = self.solarSpec.flambda
        # This one isn't as bad as the model grids, maybe we could get away with computing the magnitudes
        # in the __call__ each time.
        if mags:
            # Load up the LSST filters and convert the solarSpec.flabda and solarSpec.wavelen to fluxes
            throughPath = os.path.join(getPackageDir('throughputs'),
                                       'baseline')
            self.lsstFilterNames = ['u', 'g', 'r', 'i', 'z', 'y']
            self.lsstEquations = np.zeros(
                (np.size(self.lsstFilterNames), np.size(self.fitResults['B'])),
                dtype=float)
            self.lsstEffWave = []

            fits = np.empty(
                (np.size(self.effWave), np.size(self.fitResults['B'])),
                dtype=float)
            for i, fn in enumerate(self.filterNames):
                fits[i, :] = self.fitResults[fn]

            for filtername in self.lsstFilterNames:
                bp = np.loadtxt(os.path.join(throughPath,
                                             'filter_' + filtername + '.dat'),
                                dtype=list(zip(['wave', 'trans'],
                                               [float] * 2)))
                tempB = Bandpass()
                tempB.setBandpass(bp['wave'], bp['trans'])
                self.lsstEffWave.append(tempB.calcEffWavelen()[0])
            # Loop through the parameters and interpolate to new eff wavelengths
            for i in np.arange(self.lsstEquations[0, :].size):
                interp = InterpolatedUnivariateSpline(self.effWave, fits[:, i])
                self.lsstEquations[:, i] = interp(self.lsstEffWave)
            # Set the dark sky flux
            for i, filterName in enumerate(self.lsstFilterNames):
                self.lsstEquations[i, -1] = 10.**(
                    -0.4 * (darkSkyMags[filterName] - np.log10(3631.)))

        self.filterNameDict = {'u': 0, 'g': 1, 'r': 2, 'i': 3, 'z': 4, 'y': 5}
    def __init__(self, mags=False, darkSkyMags=None, fitResults=None):
        """
        Read the Solar spectrum into a handy object and compute mags in different filters
        mags:  If true, only return the LSST filter magnitudes, otherwise return the full spectrum

        darkSkyMags = dict of the zenith dark sky values to be assumed. The twilight fits are
        done relative to the dark sky level.
        fitResults = dict of twilight parameters based on twilightFunc. Keys should be filter names.
        """

        if darkSkyMags is None:
            darkSkyMags = {'u': 22.8, 'g': 22.3, 'r': 21.2,
                           'i': 20.3, 'z': 19.3, 'y': 18.0,
                           'B': 22.35, 'G': 21.71, 'R': 21.3}

        self.mags = mags

        dataDir = getPackageDir('sims_skybrightness_data')

        solarSaved = np.load(os.path.join(dataDir, 'solarSpec/solarSpec.npz'))
        self.solarSpec = Sed(wavelen=solarSaved['wave'], flambda=solarSaved['spec'])
        solarSaved.close()

        canonFilters = {}
        fnames = ['blue_canon.csv', 'green_canon.csv', 'red_canon.csv']

        # Filter names, from bluest to reddest.
        self.filterNames = ['B', 'G', 'R']

        for fname, filterName in zip(fnames, self.filterNames):
            bpdata = np.genfromtxt(os.path.join(dataDir, 'Canon/', fname), delimiter=', ',
                                   dtype=list(zip(['wave', 'through'], [float]*2)))
            bpTemp = Bandpass()
            bpTemp.setBandpass(bpdata['wave'], bpdata['through'])
            canonFilters[filterName] = bpTemp

        # Tack on the LSST filters
        throughPath = os.path.join(getPackageDir('throughputs'), 'baseline')
        lsstKeys = ['u', 'g', 'r', 'i', 'z', 'y']
        for key in lsstKeys:
            bp = np.loadtxt(os.path.join(throughPath, 'filter_'+key+'.dat'),
                            dtype=list(zip(['wave', 'trans'], [float]*2)))
            tempB = Bandpass()
            tempB.setBandpass(bp['wave'], bp['trans'])
            canonFilters[key] = tempB
            self.filterNames.append(key)

        # MAGIC NUMBERS from fitting the all-sky camera:
        # Code to generate values in sims_skybrightness/examples/fitTwiSlopesSimul.py
        # Which in turn uses twilight maps from sims_skybrightness/examples/buildTwilMaps.py
        # values are of the form:
        # 0: ratio of f^z_12 to f_dark^z
        # 1: slope of curve wrt sun alt
        # 2: airmass term (10^(arg[2]*(X-1)))
        # 3: azimuth term.
        # 4: zenith dark sky flux (erg/s/cm^2)

        # For z and y, just assuming the shape parameter fits are similar to the other bands.
        # Looks like the diode is not sensitive enough to detect faint sky.
        # Using the Patat et al 2006 I-band values for z and modeified a little for y as a temp fix.
        if fitResults is None:
            self.fitResults = {'B': [7.56765633e+00, 2.29798055e+01, 2.86879956e-01,
                                     3.01162143e-01, 2.58462036e-04],
                               'G': [2.38561156e+00, 2.29310648e+01, 2.97733083e-01,
                                     3.16403197e-01, 7.29660095e-04],
                               'R': [1.75498017e+00, 2.22011802e+01, 2.98619033e-01,
                                     3.28880254e-01, 3.24411056e-04],
                               'z': [2.29, 24.08, 0.3, 0.3, -666],
                               'y': [2.0, 24.08, 0.3, 0.3, -666]}

            # XXX-completely arbitrary fudge factor to make things brighter in the blue
            # Just copy the blue and say it's brighter.
            self.fitResults['u'] = [16., 2.29622121e+01, 2.85862729e-01,
                                    2.99902574e-01, 2.32325117e-04]
        else:
            self.fitResults = fitResults

        # Take out any filters that don't have fit results
        self.filterNames = [key for key in self.filterNames if key in self.fitResults]

        self.effWave = []
        self.solarMag = []
        for filterName in self.filterNames:
            self.effWave.append(canonFilters[filterName].calcEffWavelen()[0])
            self.solarMag.append(self.solarSpec.calcMag(canonFilters[filterName]))

        ord = np.argsort(self.effWave)
        self.filterNames = np.array(self.filterNames)[ord]
        self.effWave = np.array(self.effWave)[ord]
        self.solarMag = np.array(self.solarMag)[ord]

        # update the fit results to be zeropointed properly
        for key in self.fitResults:
            f0 = 10.**(-0.4*(darkSkyMags[key]-np.log10(3631.)))
            self.fitResults[key][-1] = f0

        self.solarWave = self.solarSpec.wavelen
        self.solarFlux = self.solarSpec.flambda
        # This one isn't as bad as the model grids, maybe we could get away with computing the magnitudes
        # in the __call__ each time.
        if mags:
            # Load up the LSST filters and convert the solarSpec.flabda and solarSpec.wavelen to fluxes
            throughPath = os.path.join(getPackageDir('throughputs'), 'baseline')
            self.lsstFilterNames = ['u', 'g', 'r', 'i', 'z', 'y']
            self.lsstEquations = np.zeros((np.size(self.lsstFilterNames),
                                           np.size(self.fitResults['B'])), dtype=float)
            self.lsstEffWave = []

            fits = np.empty((np.size(self.effWave), np.size(self.fitResults['B'])), dtype=float)
            for i, fn in enumerate(self.filterNames):
                fits[i, :] = self.fitResults[fn]

            for filtername in self.lsstFilterNames:
                bp = np.loadtxt(os.path.join(throughPath, 'filter_'+filtername+'.dat'),
                                dtype=list(zip(['wave', 'trans'], [float]*2)))
                tempB = Bandpass()
                tempB.setBandpass(bp['wave'], bp['trans'])
                self.lsstEffWave.append(tempB.calcEffWavelen()[0])
            # Loop through the parameters and interpolate to new eff wavelengths
            for i in np.arange(self.lsstEquations[0, :].size):
                interp = InterpolatedUnivariateSpline(self.effWave, fits[:, i])
                self.lsstEquations[:, i] = interp(self.lsstEffWave)
            # Set the dark sky flux
            for i, filterName in enumerate(self.lsstFilterNames):
                self.lsstEquations[i, -1] = 10.**(-0.4*(darkSkyMags[filterName]-np.log10(3631.)))

        self.filterNameDict = {'u': 0, 'g': 1, 'r': 2, 'i': 3, 'z': 4, 'y': 5}