예제 #1
0
    def __init__(self, m5Col='fiveSigmaDepth', metricName='ExgalM5', units='mag',
                 lsstFilter='r', wavelen_min=None , wavelen_max=None , **kwargs):
        # Set the name for the dust map to use. This is gathered into the MetricBundle.
        maps = ['DustMap']
        # Set the default wavelength limits for the lsst filters. These are approximately correct.
        waveMins = {'u':330.,'g':403.,'r':552.,'i':691.,'z':818.,'y':950.}
        waveMaxes = {'u':403.,'g':552.,'r':691.,'i':818.,'z':922.,'y':1070.}
        if lsstFilter is not None:
            wavelen_min = waveMins[lsstFilter]
            wavelen_max = waveMaxes[lsstFilter]

        self.m5Col = m5Col
        super().__init__(col=[self.m5Col], maps=maps, metricName=metricName, units=units, **kwargs)

        # Set up internal values for the dust extinction.
        testsed = Sed()
        testsed.setFlatSED(wavelen_min=wavelen_min, wavelen_max=wavelen_max, wavelen_step=1.0)
        testbandpass = Bandpass(wavelen_min=wavelen_min, wavelen_max=wavelen_max, wavelen_step=1.0)
        testbandpass.setBandpass(wavelen=testsed.wavelen,
                                 sb=np.ones(len(testsed.wavelen)))
        self.R_v = 3.1
        self.ref_ebv = 1.0
        # Calculate non-dust-extincted magnitude
        flatmag = testsed.calcMag(testbandpass)
        # Add dust
        self.a, self.b = testsed.setupCCM_ab()
        testsed.addDust(self.a, self.b, ebv=self.ref_ebv, R_v=self.R_v)
        # Calculate difference due to dust when EBV=1.0 (m_dust = m_nodust - Ax, Ax > 0)
        self.Ax1 = testsed.calcMag(testbandpass) - flatmag
        # We will call Coaddm5Metric to calculate the coadded depth. Set it up here.
        self.Coaddm5Metric = Coaddm5Metric(m5Col=m5Col)
예제 #2
0
 def _calcColors(self, sedname='C.dat'):
     """
     Calculate the colors for a moving object with sed 'sedname'.
     """
     # Do we need to read in the LSST bandpasses?
     try:
         self.lsst
     except AttributeError:
         filterdir = os.getenv('LSST_THROUGHPUTS_BASELINE')
         filterlist = ('u', 'g', 'r', 'i', 'z', 'y')
         self.lsst ={}
         for f in filterlist:
             self.lsst[f] = Bandpass()
             self.lsst[f].readThroughput(os.path.join(filterdir, 'total_'+f+'.dat'))
         self.vband = Bandpass()
         self.vband.readThroughput('harris_V.dat')
         self.colors = {}
     # See if the sed's colors are in memory already.
     if sedname not in self.colors:
         moSed = Sed()
         moSed.readSED_flambda(sedname)
         vmag = moSed.calcMag(self.vband)
         self.colors[sedname] = {}
         for f in filterlist:
             self.colors[sedname][f] = moSed.calcMag(self.lsst[f]) - vmag
     return self.colors[sedname]
예제 #3
0
    def calcColors(self, sedname='C.dat', sedDir=None):
        """Calculate the colors for a given SED.

        If the sedname is not already in the dictionary self.colors, this reads the
        SED from disk and calculates all V-[filter] colors for all filters in self.filterlist.
        The result is stored in self.colors[sedname][filter].

        Parameters
        ----------
        sedname : str (opt)
            Name of the SED. Default 'C.dat'.
        sedDir : str (opt)
            Directory containing the SEDs of the moving objects.
            Default None = $SIMS_MOVINGOBJECTS_DIR/data.

        Returns
        -------
        dict
            Dictionary of the colors in self.filterlist for this particular Sed.
        """
        if sedname not in self.colors:
            if sedDir is None:
                sedDir = os.path.join(getPackageDir('SIMS_MOVINGOBJECTS'),
                                      'data')
            moSed = Sed()
            moSed.readSED_flambda(os.path.join(sedDir, sedname))
            vmag = moSed.calcMag(self.vband)
            self.colors[sedname] = {}
            for f in self.filterlist:
                self.colors[sedname][f] = moSed.calcMag(self.lsst[f]) - vmag
        return self.colors[sedname]
예제 #4
0
    def testMagListForSedList(self):
        """
        Test that magListForSedList calculates the correct magnitude
        """

        nBandpasses = 7
        bpNameList, bpList = self.getListOfBandpasses(nBandpasses)
        testBpDict = BandpassDict(bpList, bpNameList)

        nSed = 20
        sedNameList = self.getListOfSedNames(nSed)
        magNormList = self.rng.random_sample(nSed)*5.0 + 15.0
        internalAvList = self.rng.random_sample(nSed)*0.3 + 0.1
        redshiftList = self.rng.random_sample(nSed)*5.0
        galacticAvList = self.rng.random_sample(nSed)*0.3 + 0.1

        # first, test on an SedList without a wavelenMatch
        testSedList = SedList(sedNameList, magNormList,
                              fileDir=self.sedDir,
                              internalAvList=internalAvList,
                              redshiftList=redshiftList,
                              galacticAvList=galacticAvList)

        magList = testBpDict.magListForSedList(testSedList)
        self.assertEqual(magList.shape[0], nSed)
        self.assertEqual(magList.shape[1], nBandpasses)

        for ix, sedObj in enumerate(testSedList):
            dummySed = Sed(wavelen=copy.deepcopy(sedObj.wavelen),
                           flambda=copy.deepcopy(sedObj.flambda))

            for iy, bp in enumerate(testBpDict):
                mag = dummySed.calcMag(bpList[iy])
                self.assertAlmostEqual(mag, magList[ix][iy], 2)

        # now use wavelenMatch
        testSedList = SedList(sedNameList, magNormList,
                              fileDir=self.sedDir,
                              internalAvList=internalAvList,
                              redshiftList=redshiftList,
                              galacticAvList=galacticAvList,
                              wavelenMatch=testBpDict.wavelenMatch)

        magList = testBpDict.magListForSedList(testSedList)
        self.assertEqual(magList.shape[0], nSed)
        self.assertEqual(magList.shape[1], nBandpasses)

        for ix, sedObj in enumerate(testSedList):
            dummySed = Sed(wavelen=copy.deepcopy(sedObj.wavelen),
                           flambda=copy.deepcopy(sedObj.flambda))

            for iy, bp in enumerate(testBpDict):
                mag = dummySed.calcMag(bpList[iy])
                self.assertAlmostEqual(mag, magList[ix][iy], 2)
예제 #5
0
def get_sed(name, magnorm, redshift, av, rv):
    if not hasattr(get_sed, '_rest_dict'):
        get_sed._rest_dict = {}
        get_sed._imsim_bp = Bandpass()
        get_sed._imsim_bp.imsimBandpass()
        get_sed._sed_dir = os.environ['SIMS_SED_LIBRARY_DIR']
        get_sed._ccm_w = None

    tag = '%s_%.2f_%.2f' % (name, av, rv)
    if tag not in get_sed._rest_dict:
        ss = Sed()
        ss.readSED_flambda(os.path.join(get_sed._sed_dir, name))
        if get_sed._ccm_w is None or not np.array_equal(
                ss.wavelen, get_sed._ccm_w):
            get_sed._ccm_w = np.copy(ss.wavelen)
            get_sed._ax, get_sed._bx = ss.setupCCM_ab()

        mn = ss.calcMag(get_sed._imsim_bp)
        ss.addDust(get_sed._ax, get_sed._bx, A_v=av, R_v=rv)
        get_sed._rest_dict[tag] = (ss, mn)

    base_sed = get_sed._rest_dict[tag][0]
    ss = Sed(wavelen=base_sed.wavelen, flambda=base_sed.flambda)
    dmag = magnorm - get_sed._rest_dict[tag][1]
    fnorm = np.power(10.0, -0.4 * dmag)
    ss.multiplyFluxNorm(fnorm)
    ss.redshiftSED(redshift, dimming=True)
    return ss
    def returnMags(self, bandpass=None):
        """
        Convert the computed spectra to magnitudes using the supplied bandpasses,
        or, if self.mags=True, just return the mags in the LSST filters

        If mags=True when initialized, return mags returns an structured array with
        dtype names u,g,r,i,z,y.
        """
        if self.mags:
            if bandpass:
                warnings.warn('Ignoring set bandpasses and returning LSST ugrizy.')
            mags = -2.5*np.log10(self.spec)+np.log10(3631.)
            # Mask out high airmass
            mags[self.mask] *= np.nan
            # Convert to a structured array
            mags = np.core.records.fromarrays(mags.transpose(),
                                              names='u,g,r,i,z,y',
                                              formats='float,'*6)
        else:
            mags = np.zeros(self.npts, dtype=float)-666
            tempSed = Sed()
            isThrough = np.where(bandpass.sb > 0)
            minWave = bandpass.wavelen[isThrough].min()
            maxWave = bandpass.wavelen[isThrough].max()
            inBand = np.where((self.wave >= minWave) & (self.wave <= maxWave))
            for i, ra in enumerate(self.ra):
                # Check that there is flux in the band, otherwise calcMag fails
                if np.max(self.spec[i, inBand]) > 0:
                    tempSed.setSED(self.wave, flambda=self.spec[i, :])
                    mags[i] = tempSed.calcMag(bandpass)

            # Mask out high airmass
            mags[self.mask] *= np.nan
        return mags
예제 #7
0
def _create_library_one_sed(_galaxy_sed_dir, sed_file_name_list, av_grid,
                            rv_grid, bandpass_dict, out_dict, out_lock):

    n_obj = 0
    for i_av, av in enumerate(av_grid):
        for i_rv, rv in enumerate(rv_grid):
            if av < 0.01 and i_rv > 0:
                continue
            n_obj += 1

    imsim_bp = Bandpass()
    imsim_bp.imsimBandpass()

    t_start = time.time()

    sed_names_out = []
    rv_out_list_out = []
    av_out_list_out = []
    sed_mag_norm_out = []
    sed_mag_list_out = []

    for i_sed, sed_file_name in enumerate(sed_file_name_list):
        base_spec = Sed()
        base_spec.readSED_flambda(os.path.join(_galaxy_sed_dir, sed_file_name))
        ax, bx = base_spec.setupCCM_ab()

        mag_norm = base_spec.calcMag(imsim_bp)

        sed_names = np.array([defaultSpecMap[sed_file_name]] * n_obj)
        rv_out_list = np.zeros(n_obj, dtype=float)
        av_out_list = np.zeros(n_obj, dtype=float)
        sed_mag_norm = mag_norm * np.ones(n_obj, dtype=float)
        sed_mag_list = np.zeros((n_obj, len(bandpass_dict)), dtype=float)

        i_obj = 0
        for i_av, av in enumerate(av_grid):
            for i_rv, rv in enumerate(rv_grid):
                if av < 0.01 and i_rv > 0:
                    continue
                spec = Sed(wavelen=base_spec.wavelen,
                           flambda=base_spec.flambda)
                spec.addDust(ax, bx, A_v=av, R_v=rv)
                av_out_list[i_obj] = av
                rv_out_list[i_obj] = rv
                sed_mag_list[i_obj][:] = bandpass_dict.magListForSed(spec)
                i_obj += 1

        sed_names_out.append(sed_names)
        sed_mag_norm_out.append(sed_mag_norm)
        sed_mag_list_out.append(sed_mag_list)
        av_out_list_out.append(av_out_list)
        rv_out_list_out.append(rv_out_list)

    with out_lock:
        out_dict['sed_names'] += sed_names_out
        out_dict['sed_mag_norm'] += sed_mag_norm_out
        out_dict['sed_mag_list'] += sed_mag_list_out
        out_dict['av_out_list'] += av_out_list_out
        out_dict['rv_out_list'] += rv_out_list_out
예제 #8
0
파일: proto2.py 프로젝트: mjuric/MafSSO
def calcColors(sedname='C.dat'):
    # Calculate SSO colors.
    filterdir = os.getenv('LSST_THROUGHPUTS_BASELINE')
    filterlist = ('u', 'g', 'r', 'i', 'z', 'y')
    lsst ={}
    for f in filterlist:
        lsst[f] = Bandpass()
        lsst[f].readThroughput(os.path.join(filterdir, 'total_'+f+'.dat'))
    vband = Bandpass()
    vband.readThroughput('harris_V.dat')
    csed = Sed()
    csed.readSED_flambda(sedname)
    vmag = csed.calcMag(vband)
    dmags = {}
    for f in filterlist:
        dmags[f] = csed.calcMag(lsst[f]) - vmag
    return dmags
예제 #9
0
    def test_stars(self):
        obs = ObservationMetaData(bandpassName=['c_u', 'c_g'], m5=[25.0, 26.0])

        db_dtype = np.dtype([('id', np.int), ('raJ2000', np.float),
                             ('decJ2000', np.float), ('sedFilename', str, 100),
                             ('magNorm', np.float), ('galacticAv', np.float)])

        inputDir = os.path.join(getPackageDir('sims_catUtils'), 'tests',
                                'testData')
        inputFile = os.path.join(inputDir, 'IndicesTestCatalogStars.txt')
        db = fileDBObject(inputFile,
                          dtype=db_dtype,
                          runtable='test',
                          idColKey='id')
        cat = CartoonStars(db, obs_metadata=obs)
        with lsst.utils.tests.getTempFilePath('.txt') as catName:
            cat.write_catalog(catName)
            dtype = np.dtype([(name, np.float) for name in cat.column_outputs])
            controlData = np.genfromtxt(catName, dtype=dtype, delimiter=',')

        db_columns = db.query_columns([
            'id', 'raJ2000', 'decJ2000', 'sedFilename', 'magNorm', 'galacticAv'
        ])

        sedDir = os.path.join(getPackageDir('sims_sed_library'), 'starSED',
                              'kurucz')

        for ix, line in enumerate(next(db_columns)):
            spectrum = Sed()
            spectrum.readSED_flambda(os.path.join(sedDir, line[3]))
            fnorm = spectrum.calcFluxNorm(line[4], self.normband)
            spectrum.multiplyFluxNorm(fnorm)
            a_x, b_x = spectrum.setupCCM_ab()
            spectrum.addDust(a_x, b_x, A_v=line[5])
            umag = spectrum.calcMag(self.uband)
            self.assertAlmostEqual(umag, controlData['cartoon_u'][ix], 3)
            gmag = spectrum.calcMag(self.gband)
            self.assertAlmostEqual(gmag, controlData['cartoon_g'][ix], 3)
            umagError, gamma = calcMagError_m5(umag, self.uband, obs.m5['c_u'],
                                               PhotometricParameters())
            gmagError, gamma = calcMagError_m5(gmag, self.gband, obs.m5['c_g'],
                                               PhotometricParameters())
            self.assertAlmostEqual(umagError,
                                   controlData['sigma_cartoon_u'][ix], 3)
            self.assertAlmostEqual(gmagError,
                                   controlData['sigma_cartoon_g'][ix], 3)
예제 #10
0
 def get_mags(self,source, phase ):
     
     sed = Sed()
     print "==========================================="
     print phase
     print "==========================================="
     if phase > -20 and phase < 50 :
         sourceflux = source.flux(phase=phase, wave=self.rband.wavelen*10.)
         sed.setSED(wavelen=self.rband.wavelen, flambda=sourceflux/10.)
     else:
         sed.setSED(wavelen=self.rband.wavelen, flambda=flambda)
     #sed.redshiftSED(redshift=_z[i], dimming=True)
     return [sed.calcMag(bandpass=self.uband),
             sed.calcMag(bandpass=self.gband),
             sed.calcMag(bandpass=self.rband),
             sed.calcMag(bandpass=self.iband),
             sed.calcMag(bandpass=self.zband)]
예제 #11
0
def _get_sed_mags_and_cosmology(catalog_name):
    """
    Returns 3 numpy arrays: sed_names, sed_mag_list, sed_mag_norm
    and a dictionary for cosmology
    sed_names is 1d str array, with length = number of SED files in the library
    sed_mag_list is MxN float array, with M = number of SED files in the library,
        and N = number of top hat filters in the catalog
    sed_mag_norm is 1d float array, with length = number of SED files in the library
    cosmology = {'H0': H0, 'Om0': Om0}
    """
    gc = GCRCatalogs.load_catalog(catalog_name,
                                  config_overwrite=dict(md5=False))
    cosmo = dict(H0=gc.cosmology.H0.value, Om0=gc.cosmology.Om0)

    bp_params_raw = {'disk': set(), 'bulge': set()}
    for q in gc.list_all_quantities():
        m = _gcr_sed_re.match(q)
        if m:
            wav0, width, tag = m.groups()
            bp_params_raw[tag].add((int(wav0), int(width)))
    assert bp_params_raw['disk'] == bp_params_raw[
        'bulge'], 'SEDs for disk and bulge do not match'
    assert bp_params_raw['disk'], 'No SED found'

    bp_params_sorted = sorted(bp_params_raw['disk'], key=lambda p: p[0])

    # SED labels in GCR specify the band pass in angstrom, but CatSim uses nm
    # Hence the conversion factor 0.1 in the code below
    wav_min = bp_params_sorted[0][0] * 0.1
    wav_max = max((0.1 * (wav0 + width) for wav0, width in bp_params_sorted))
    wav_grid = np.arange(wav_min, wav_max, 0.1)

    bp_name_list = list()
    bp_list = list()
    for wav0, width in bp_params_sorted:
        sb_grid = ((wav_grid >= wav0 * 0.1) &
                   (wav_grid <= (wav0 + width) * 0.1)).astype(float)
        bp_list.append(Bandpass(wavelen=wav_grid, sb=sb_grid))
        bp_name_list.append('%d_%d' % (wav0, width))

    bandpass_dict = BandpassDict(bp_list, bp_name_list)

    sed_names = list()
    sed_mag_list = list()
    sed_mag_norm = list()

    imsim_bp = Bandpass()
    imsim_bp.imsimBandpass()

    for sed_file_name in os.listdir(_galaxy_sed_dir):
        spec = Sed()
        spec.readSED_flambda(os.path.join(_galaxy_sed_dir, sed_file_name))
        sed_names.append(sed_file_name)
        sed_mag_list.append(tuple(bandpass_dict.magListForSed(spec)))
        sed_mag_norm.append(spec.calcMag(imsim_bp))

    return np.array(sed_names), np.array(sed_mag_list), np.array(
        sed_mag_norm), cosmo
예제 #12
0
    def calcMagNorm(self,
                    objectMags,
                    sedObj,
                    bandpassDict,
                    mag_error=None,
                    redshift=None,
                    filtRange=None):
        """
        This will find the magNorm value that gives the closest match to the magnitudes of the object
        using the matched SED. Uses scipy.optimize.leastsq to find the values of fluxNorm that minimizes
        the function: ((flux_obs - (fluxNorm*flux_model))/flux_error)**2.

        @param [in] objectMags are the magnitude values for the object with extinction matching that of
        the SED object. In the normal case using the selectSED routines above it will be dereddened mags.

        @param [in] sedObj is an Sed class instance that is set with the wavelength and flux of the
        matched SED

        @param [in] bandpassDict is a BandpassDict class instance with the Bandpasses set to those
        for the magnitudes given for the catalog object

        @param [in] mag_error are provided error values for magnitudes in objectMags. If none provided
        then this defaults to 1.0. This should be an array of the same length as objectMags.

        @param [in] redshift is the redshift of the object if the magnitude is observed

        @param [in] filtRange is a selected range of filters specified by their indices in the bandpassList
        to match up against. Used when missing data in some magnitude bands.

        @param [out] bestMagNorm is the magnitude normalization for the given magnitudes and SED
        """

        import scipy.optimize as opt

        sedTest = Sed()
        sedTest.setSED(sedObj.wavelen, flambda=sedObj.flambda)
        if redshift is not None:
            sedTest.redshiftSED(redshift)
        imSimBand = Bandpass()
        imSimBand.imsimBandpass()
        zp = -2.5 * np.log10(3631)  #Note using default AB zeropoint
        flux_obs = np.power(10, (objectMags + zp) / (-2.5))
        sedTest.resampleSED(wavelen_match=bandpassDict.wavelenMatch)
        sedTest.flambdaTofnu()
        flux_model = sedTest.manyFluxCalc(bandpassDict.phiArray,
                                          bandpassDict.wavelenStep)
        if filtRange is not None:
            flux_obs = flux_obs[filtRange]
            flux_model = flux_model[filtRange]
        if mag_error is None:
            flux_error = np.ones(len(flux_obs))
        else:
            flux_error = np.abs(flux_obs * (np.log(10) / (-2.5)) * mag_error)
        bestFluxNorm = opt.leastsq(
            lambda x: ((flux_obs - (x * flux_model)) / flux_error), 1.0)[0][0]
        sedTest.multiplyFluxNorm(bestFluxNorm)
        bestMagNorm = sedTest.calcMag(imSimBand)
        return bestMagNorm
예제 #13
0
    def testSignalToNoise(self):
        """
        Test that calcSNR_m5 and calcSNR_sed give similar results
        """
        defaults = LSSTdefaults()
        photParams = PhotometricParameters()

        m5 = []
        for i in range(len(self.hardwareList)):
            m5.append(
                snr.calcM5(
                    self.skySed,
                    self.bpList[i],
                    self.hardwareList[i],
                    photParams,
                    seeing=defaults.seeing(self.filterNameList[i]),
                )
            )

        sedDir = lsst.utils.getPackageDir("sims_sed_library")
        sedDir = os.path.join(sedDir, "starSED", "kurucz")
        fileNameList = os.listdir(sedDir)

        numpy.random.seed(42)
        offset = numpy.random.random_sample(len(fileNameList)) * 2.0

        for ix, name in enumerate(fileNameList):
            if ix > 100:
                break
            spectrum = Sed()
            spectrum.readSED_flambda(os.path.join(sedDir, name))
            ff = spectrum.calcFluxNorm(m5[2] - offset[ix], self.bpList[2])
            spectrum.multiplyFluxNorm(ff)
            magList = []
            controlList = []
            magList = []
            for i in range(len(self.bpList)):
                controlList.append(
                    snr.calcSNR_sed(
                        spectrum,
                        self.bpList[i],
                        self.skySed,
                        self.hardwareList[i],
                        photParams,
                        defaults.seeing(self.filterNameList[i]),
                    )
                )

                magList.append(spectrum.calcMag(self.bpList[i]))

            testList, gammaList = snr.calcSNR_m5(
                numpy.array(magList), numpy.array(self.bpList), numpy.array(m5), photParams
            )

            for tt, cc in zip(controlList, testList):
                msg = "%e != %e " % (tt, cc)
                self.assertTrue(numpy.abs(tt / cc - 1.0) < 0.001, msg=msg)
예제 #14
0
def quasarMag(z, M1450, survey, f):
    if (z, M1450, survey, f) in magCache:
        return magCache[(z, M1450, survey, f)]
    # for files containing $\lambda$ / F$_\lambda$, we use the Sed method
    # readSED_flambda. For files containing $\lambda$ / F$_\nu$,
    # we would use the readSED_fnu method instead.

    # get the path to the SED file for this z
    sedFilename = config.sedFilenameFormat.format(config.reddening, z)
    spectrumFilename = os.path.join(config.sedDir, sedFilename)

    # Read the spectrum.
    agn = Sed()
    agn.readSED_flambda(spectrumFilename)

    # Suppose you had a spectrum, but it didn't have an absolute scale. Or you
    # wanted to scale it to have a given magnitude in a particular bandpass.
    # For example, say we wanted to make our 'agn' spectrum have an r band
    # magnitude of 20, then calculate the magnitudes in all bandpasses. We
    # just use the calcFluxNorm and multiplyFluxNorm methods.

    # Scale spectrum and recalculate magnitudes.

    # given an absolute M1450, the observed magnitude m corresponding
    # to rest-frame 145nm radiation is
    # m = M1450+5log(d_L/10pc) - 2.5log(1+z)
    # so let's calculate m and then normalize our spectrum to that

    # first we need d_L = (1+z) * comoving distance
    # comoving distance is D_hubble * int_0^z dz'/sqrt(omegaM(1+z)^3+omegaLambda)
    def E(zp):
        return np.sqrt(config.omegaM * (1 + zp)**3 + config.omegaLambda)

    DC = config.DH * integrate.quad(lambda zp: 1 / E(zp), 0, z)[0]
    DL = (1 + z) * DC
    DL = DL * config.m2pc
    m = M1450 + 5 * np.log10(DL / 10) - 2.5 * np.log10(1 + z)

    # make a square bandpass at 145nm (in the quasar rest frame)
    # with a width of 1nm
    wavelen = np.arange(300, 2000, 0.1)
    sb = np.zeros(wavelen.shape)
    id1450 = int(((145 * (1 + z)) - 300) / 0.1)
    sb[id1450 - 5:id1450 + 5] = 1
    band1450 = Bandpass(wavelen=wavelen, sb=sb)

    # normalize the sed to m at the (rest-frame) 1450A bandpass
    fluxNorm = agn.calcFluxNorm(m, band1450)
    agn.multiplyFluxNorm(fluxNorm)

    # Calculate expected AB magnitudes in the requested lsst band
    bandpass = f2Throughput(survey, f)
    mag = agn.calcMag(bandpass)
    magCache[(z, M1450, survey, f)] = mag
    return mag
예제 #15
0
def _parallel_fitting(mag_array, redshift, redshift_true, H0, Om0, wav_min,
                      wav_width, lsst_mag_array, out_dict, tag):
    pid = os.getpid()
    (sed_names, mag_norms, av_arr,
     rv_arr) = sed_from_galacticus_mags(mag_array, redshift, redshift_true, H0,
                                        Om0, wav_min, wav_width,
                                        lsst_mag_array)

    tot_bp_dict = BandpassDict.loadTotalBandpassesFromFiles()

    sed_dir = getPackageDir('sims_sed_library')
    lsst_fit_fluxes = np.zeros((6, len(sed_names)), dtype=float)
    t_start = time.time()

    ccm_w = None
    restframe_seds = {}
    imsim_bp = Bandpass()
    imsim_bp.imsimBandpass()
    n04_ln10 = -0.4 * np.log(10)

    for ii in range(len(sed_names)):
        av_val = av_arr[ii]
        rv_val = rv_arr[ii]

        sed_tag = '%s_%.3f_%.3f' % (sed_names[ii], av_val, rv_val)
        if sed_tag not in restframe_seds:
            rest_sed = Sed()
            rest_sed.readSED_flambda(os.path.join(sed_dir, sed_names[ii]))
            mag = rest_sed.calcMag(imsim_bp)
            if ccm_w is None or not np.array_equal(rest_sed.wavelen, ccm_w):
                ccm_w = np.copy(rest_sed.wavelen)
                ax, bx = rest_sed.setupCCM_ab()
            rest_sed.addDust(ax, bx, A_v=av_val, R_v=rv_val)
            restframe_seds[sed_tag] = (rest_sed, mag)

        for i_bp, bp in enumerate('ugrizy'):
            m_norm = mag_norms[i_bp][ii]
            if m_norm > 0.0 and not np.isfinite(m_norm):
                continue

            spec = Sed(wavelen=restframe_seds[sed_tag][0].wavelen,
                       flambda=restframe_seds[sed_tag][0].flambda)
            fnorm = np.exp(n04_ln10 * (m_norm - restframe_seds[sed_tag][1]))
            try:
                assert np.isfinite(fnorm)
                assert fnorm > 0.0
            except AssertionError:
                print('\n\nmagnorm %e\n\n' % (m_norm))
                raise
            spec.multiplyFluxNorm(fnorm)
            spec.redshiftSED(redshift[ii], dimming=True)
            ff = spec.calcFlux(tot_bp_dict[bp])
            lsst_fit_fluxes[i_bp][ii] = ff

    out_dict[tag] = (sed_names, mag_norms, av_arr, rv_arr, lsst_fit_fluxes)
예제 #16
0
    def calcMagNorm(self, objectMags, sedObj, bandpassDict, mag_error = None,
                    redshift = None, filtRange = None):

        """
        This will find the magNorm value that gives the closest match to the magnitudes of the object
        using the matched SED. Uses scipy.optimize.leastsq to find the values of fluxNorm that minimizes
        the function: ((flux_obs - (fluxNorm*flux_model))/flux_error)**2.

        @param [in] objectMags are the magnitude values for the object with extinction matching that of
        the SED object. In the normal case using the selectSED routines above it will be dereddened mags.

        @param [in] sedObj is an Sed class instance that is set with the wavelength and flux of the
        matched SED

        @param [in] bandpassDict is a BandpassDict class instance with the Bandpasses set to those
        for the magnitudes given for the catalog object

        @param [in] mag_error are provided error values for magnitudes in objectMags. If none provided
        then this defaults to 1.0. This should be an array of the same length as objectMags.

        @param [in] redshift is the redshift of the object if the magnitude is observed

        @param [in] filtRange is a selected range of filters specified by their indices in the bandpassList
        to match up against. Used when missing data in some magnitude bands.

        @param [out] bestMagNorm is the magnitude normalization for the given magnitudes and SED
        """

        import scipy.optimize as opt

        sedTest = Sed()
        sedTest.setSED(sedObj.wavelen, flambda = sedObj.flambda)
        if redshift is not None:
            sedTest.redshiftSED(redshift)
        imSimBand = Bandpass()
        imSimBand.imsimBandpass()
        zp = -2.5*np.log10(3631)  #Note using default AB zeropoint
        flux_obs = np.power(10,(objectMags + zp)/(-2.5))
        sedTest.resampleSED(wavelen_match=bandpassDict.wavelenMatch)
        sedTest.flambdaTofnu()
        flux_model = sedTest.manyFluxCalc(bandpassDict.phiArray, bandpassDict.wavelenStep)
        if filtRange is not None:
            flux_obs = flux_obs[filtRange]
            flux_model = flux_model[filtRange]
        if mag_error is None:
            flux_error = np.ones(len(flux_obs))
        else:
            flux_error = np.abs(flux_obs*(np.log(10)/(-2.5))*mag_error)
        bestFluxNorm = opt.leastsq(lambda x: ((flux_obs - (x*flux_model))/flux_error), 1.0)[0][0]
        sedTest.multiplyFluxNorm(bestFluxNorm)
        bestMagNorm = sedTest.calcMag(imSimBand)
        return bestMagNorm
    def test_stars(self):
        obs = ObservationMetaData(bandpassName=['c_u', 'c_g'], m5=[25.0, 26.0])

        db_dtype = np.dtype([('id', np.int),
                             ('raJ2000', np.float),
                             ('decJ2000', np.float),
                             ('sedFilename', str, 100),
                             ('magNorm', np.float),
                             ('galacticAv', np.float)])

        inputDir = os.path.join(getPackageDir('sims_catUtils'), 'tests', 'testData')
        inputFile = os.path.join(inputDir, 'IndicesTestCatalogStars.txt')
        db = fileDBObject(inputFile, dtype=db_dtype, runtable='test', idColKey='id')
        cat = CartoonStars(db, obs_metadata=obs)
        with lsst.utils.tests.getTempFilePath('.txt') as catName:
            cat.write_catalog(catName)
            dtype = np.dtype([(name, np.float) for name in cat.column_outputs])
            controlData = np.genfromtxt(catName, dtype=dtype, delimiter=',')

        db_columns = db.query_columns(['id', 'raJ2000', 'decJ2000', 'sedFilename', 'magNorm', 'galacticAv'])

        sedDir = os.path.join(getPackageDir('sims_sed_library'), 'starSED', 'kurucz')

        for ix, line in enumerate(next(db_columns)):
            spectrum = Sed()
            spectrum.readSED_flambda(os.path.join(sedDir, line[3]))
            fnorm = spectrum.calcFluxNorm(line[4], self.normband)
            spectrum.multiplyFluxNorm(fnorm)
            a_x, b_x = spectrum.setupCCM_ab()
            spectrum.addDust(a_x, b_x, A_v=line[5])
            umag = spectrum.calcMag(self.uband)
            self.assertAlmostEqual(umag, controlData['cartoon_u'][ix], 3)
            gmag = spectrum.calcMag(self.gband)
            self.assertAlmostEqual(gmag, controlData['cartoon_g'][ix], 3)
            umagError, gamma = calcMagError_m5(umag, self.uband, obs.m5['c_u'], PhotometricParameters())
            gmagError, gamma = calcMagError_m5(gmag, self.gband, obs.m5['c_g'], PhotometricParameters())
            self.assertAlmostEqual(umagError, controlData['sigma_cartoon_u'][ix], 3)
            self.assertAlmostEqual(gmagError, controlData['sigma_cartoon_g'][ix], 3)
예제 #18
0
    def __init__(self, R_v=3.1, bandpassDict=None, ref_ebv=1.):
        # Calculate dust extinction values
        self.Ax1 = {}
        if bandpassDict is None:
            bandpassDict = BandpassDict.loadTotalBandpassesFromFiles(
                ['u', 'g', 'r', 'i', 'z', 'y'])

        for filtername in bandpassDict:
            wavelen_min = bandpassDict[filtername].wavelen.min()
            wavelen_max = bandpassDict[filtername].wavelen.max()
            testsed = Sed()
            testsed.setFlatSED(wavelen_min=wavelen_min,
                               wavelen_max=wavelen_max,
                               wavelen_step=1.0)
            self.ref_ebv = ref_ebv
            # Calculate non-dust-extincted magnitude
            flatmag = testsed.calcMag(bandpassDict[filtername])
            # Add dust
            a, b = testsed.setupCCM_ab()
            testsed.addDust(a, b, ebv=self.ref_ebv, R_v=R_v)
            # Calculate difference due to dust when EBV=1.0 (m_dust = m_nodust - Ax, Ax > 0)
            self.Ax1[filtername] = testsed.calcMag(
                bandpassDict[filtername]) - flatmag
예제 #19
0
    def test_k_correction(self):
        """
        Test that the K correction correctly converts absolute magnitude
        to observed magnitude.
        """
        bp_dict = BandpassDict.loadTotalBandpassesFromFiles()
        rng = np.random.RandomState(41321)
        sed_dir = os.path.join(getPackageDir('sims_sed_library'), 'galaxySED')
        list_of_sed_files = os.listdir(sed_dir)
        list_of_sed_files.sort()
        sed_to_check = rng.choice(list_of_sed_files, size=10)
        redshift_arr = rng.random_sample(len(sed_to_check)) * 2.0 + 0.1

        bp = bp_dict['g']
        for sed_name, zz in zip(sed_to_check, redshift_arr):
            full_name = os.path.join(sed_dir, sed_name)
            ss = Sed()
            ss.readSED_flambda(full_name)
            true_rest_mag = ss.calcMag(bp)
            ss.redshiftSED(zz, dimming=True)
            obs_mag = ss.calcMag(bp)
            k_corr = k_correction(ss, bp, zz)
            self.assertLess(np.abs(true_rest_mag - obs_mag + k_corr), 0.001)
예제 #20
0
def _create_sed_library_mags(wav_min, wav_width):
    """
    Calculate the magnitudes of the SEDs in sims_sed_library dir in the
    tophat filters specified by wav_min, wav_width

    Parameters
    ----------
    wav_min is a numpy array of the minimum wavelengths of the tophat
    filters (in nm)

    wav_width is a numpy array of the widths of the tophat filters (in nm)

    Returns
    -------
    sed_names is an array containing the names of the SED files

    sed_mag_list is MxN float array, with M = number of SED files in the library,
        and N = number of top hat filters in the catalog

    sed_mag_norm is 1d float array, with length = number of SED files in the library
    """

    wav_max = max((wav0 + width for wav0, width in zip(wav_min, wav_width)))
    wav_grid = np.arange(wav_min.min(), wav_max, 0.1)

    bp_name_list = list()
    bp_list = list()
    for wav0, width in zip(wav_min, wav_width):
        sb_grid = ((wav_grid >= wav0) & (wav_grid <=
                                         (wav0 + width))).astype(float)
        bp_list.append(Bandpass(wavelen=wav_grid, sb=sb_grid))
        bp_name_list.append('%d_%d' % (wav0, width))

    bandpass_dict = BandpassDict(bp_list, bp_name_list)

    sed_names = list()
    sed_mag_list = list()
    sed_mag_norm = list()

    imsim_bp = Bandpass()
    imsim_bp.imsimBandpass()

    for sed_file_name in os.listdir(_galaxy_sed_dir):
        spec = Sed()
        spec.readSED_flambda(os.path.join(_galaxy_sed_dir, sed_file_name))
        sed_names.append(defaultSpecMap[sed_file_name])
        sed_mag_list.append(tuple(bandpass_dict.magListForSed(spec)))
        sed_mag_norm.append(spec.calcMag(imsim_bp))

    return np.array(sed_names), np.array(sed_mag_list), np.array(sed_mag_norm)
예제 #21
0
 def _calcColors(self, sedname='C.dat', sedDir=None):
     """
     Calculate the colors for a moving object with sed 'sedname'.
     """
     # Do we need to read in the LSST bandpasses?
     try:
         self.lsst
     except AttributeError:
         envvar = 'LSST_THROUGHPUTS_BASELINE'
         filterdir = os.getenv(envvar)
         if filterdir is None:
             raise RuntimeError(
                 'Cannot find directory for throughput curves. Set env var %s'
                 % (envvar))
         self.filterlist = ('u', 'g', 'r', 'i', 'z', 'y')
         self.lsst = {}
         for f in self.filterlist:
             self.lsst[f] = Bandpass()
             self.lsst[f].readThroughput(
                 os.path.join(filterdir, 'total_' + f + '.dat'))
         self.seddir = sedDir
         if self.seddir is None:
             self.seddir = os.path.join(getPackageDir('SIMS_MOVINGOBJECTS'),
                                        'data')
         self.vband = Bandpass()
         self.vband.readThroughput(os.path.join(self.seddir,
                                                'harris_V.dat'))
         self.colors = {}
     # See if the sed's colors are in memory already.
     if sedname not in self.colors:
         moSed = Sed()
         moSed.readSED_flambda(os.path.join(self.seddir, sedname))
         vmag = moSed.calcMag(self.vband)
         self.colors[sedname] = {}
         for f in self.filterlist:
             self.colors[sedname][f] = moSed.calcMag(self.lsst[f]) - vmag
     return self.colors[sedname]
예제 #22
0
    def calcColors(self, sedname='C.dat', sedDir=None):
        """
        Calculate the colors for a given SED, store the result.

        Parameters
        ----------
        sedname : str (opt)
            Name of the SED. Default 'C.dat'.
        sedDir : str (opt)
            Directory containing the SEDs of the moving objects.
            Default None = $SIMS_MOVINGOBJECTS_DIR/data.
        """
        # See if the sed's colors are in memory already.
        if sedname not in self.colors:
            if sedDir is None:
                sedDir = os.path.join(getPackageDir('SIMS_MOVINGOBJECTS'),
                                      'data')
            moSed = Sed()
            moSed.readSED_flambda(os.path.join(sedDir, sedname))
            vmag = moSed.calcMag(self.vband)
            self.colors[sedname] = {}
            for f in self.filterlist:
                self.colors[sedname][f] = moSed.calcMag(self.lsst[f]) - vmag
        return
예제 #23
0
    def testSignalToNoise(self):
        """
        Test that calcSNR_m5 and calcSNR_sed give similar results
        """
        defaults = LSSTdefaults()
        photParams = PhotometricParameters()

        m5 = []
        for i in range(len(self.hardwareList)):
            m5.append(snr.calcM5(self.skySed, self.bpList[i],
                      self.hardwareList[i],
                      photParams, seeing=defaults.seeing(self.filterNameList[i])))


        sedDir = lsst.utils.getPackageDir('sims_sed_library')
        sedDir = os.path.join(sedDir, 'starSED', 'kurucz')
        fileNameList = os.listdir(sedDir)

        numpy.random.seed(42)
        offset = numpy.random.random_sample(len(fileNameList))*2.0

        for ix, name in enumerate(fileNameList):
            if ix>100:
                break
            spectrum = Sed()
            spectrum.readSED_flambda(os.path.join(sedDir, name))
            ff = spectrum.calcFluxNorm(m5[2]-offset[ix], self.bpList[2])
            spectrum.multiplyFluxNorm(ff)
            magList = []
            controlList = []
            magList = []
            for i in range(len(self.bpList)):
                controlList.append(snr.calcSNR_sed(spectrum, self.bpList[i],
                                               self.skySed,
                                               self.hardwareList[i],
                                               photParams, defaults.seeing(self.filterNameList[i])))

                magList.append(spectrum.calcMag(self.bpList[i]))

            testList, gammaList = snr.calcSNR_m5(numpy.array(magList),
                                        numpy.array(self.bpList),
                                        numpy.array(m5),
                                        photParams)

            for tt, cc in zip(controlList, testList):
                msg = '%e != %e ' % (tt, cc)
                self.assertTrue(numpy.abs(tt/cc - 1.0) < 0.001, msg=msg)
예제 #24
0
    def returnMags(self, bandpasses=None):
        """
        Convert the computed spectra to a magnitude using the supplied bandpass,
        or, if self.mags=True, return the mags in the LSST filters

        If mags=True when initialized, return mags returns an structured array with
        dtype names u,g,r,i,z,y.

        bandpasses: optional dictionary with bandpass name keys and bandpass object values.

        """
        if self.azs is None:
            raise ValueError(
                'No coordinates set. Use setRaDecMjd, setRaDecAltAzMjd, or setParams methods before calling returnMags.'
            )

        if self.mags:
            if bandpasses:
                warnings.warn(
                    'Ignoring set bandpasses and returning LSST ugrizy.')
            mags = -2.5 * np.log10(self.spec) + np.log10(3631.)
            # Mask out high airmass
            mags[self.mask] *= np.nan
            mags = mags.swapaxes(0, 1)
            magsBack = {}
            for i, f in enumerate(self.filterNames):
                magsBack[f] = mags[i]
        else:
            magsBack = {}
            for key in bandpasses:
                mags = np.zeros(self.npts, dtype=float) - 666
                tempSed = Sed()
                isThrough = np.where(bandpasses[key].sb > 0)
                minWave = bandpasses[key].wavelen[isThrough].min()
                maxWave = bandpasses[key].wavelen[isThrough].max()
                inBand = np.where((self.wave >= minWave)
                                  & (self.wave <= maxWave))
                for i, ra in enumerate(self.ra):
                    # Check that there is flux in the band, otherwise calcMag fails
                    if np.max(self.spec[i, inBand]) > 0:
                        tempSed.setSED(self.wave, flambda=self.spec[i, :])
                        mags[i] = tempSed.calcMag(bandpasses[key])
                # Mask out high airmass
                mags[self.mask] *= np.nan
                magsBack[key] = mags
        return magsBack
예제 #25
0
    def test_mags_vs_flux(self):
        """
        Verify that the relationship between Sed.calcMag() and Sed.calcFlux()
        is as expected
        """
        wavelen = np.arange(100.0, 1500.0, 1.0)
        flambda = np.exp(-0.5*np.power((wavelen-500.0)/100.0,2))
        sb = (wavelen-100.0)/1400.0

        ss = Sed(wavelen=wavelen, flambda=flambda)
        bp = Bandpass(wavelen=wavelen, sb=sb)

        mag = ss.calcMag(bp)
        flux = ss.calcFlux(bp)

        self.assertAlmostEqual(ss.magFromFlux(flux)/mag, 1.0, 10)
        self.assertAlmostEqual(ss.fluxFromMag(mag)/flux, 1.0, 10)
예제 #26
0
    def test_mags_vs_flux(self):
        """
        Verify that the relationship between Sed.calcMag() and Sed.calcFlux()
        is as expected
        """
        wavelen = np.arange(100.0, 1500.0, 1.0)
        flambda = np.exp(-0.5 * np.power((wavelen - 500.0) / 100.0, 2))
        sb = (wavelen - 100.0) / 1400.0

        ss = Sed(wavelen=wavelen, flambda=flambda)
        bp = Bandpass(wavelen=wavelen, sb=sb)

        mag = ss.calcMag(bp)
        flux = ss.calcFlux(bp)

        self.assertAlmostEqual(ss.magFromFlux(flux) / mag, 1.0, 10)
        self.assertAlmostEqual(ss.fluxFromMag(mag) / flux, 1.0, 10)
예제 #27
0
    def testMagError(self):
        """
        Make sure that calcMagError_sed and calcMagError_m5
        agree to within 0.001
        """
        defaults = LSSTdefaults()
        photParams = PhotometricParameters()

        # create a cartoon spectrum to test on
        spectrum = Sed()
        spectrum.setFlatSED()
        spectrum.multiplyFluxNorm(1.0e-9)

        # find the magnitudes of that spectrum in our bandpasses
        magList = []
        for total in self.bpList:
            magList.append(spectrum.calcMag(total))
        magList = np.array(magList)

        # try for different normalizations of the skySED
        for fNorm in np.arange(1.0, 5.0, 1.0):
            self.skySed.multiplyFluxNorm(fNorm)

            for total, hardware, filterName, mm in \
                zip(self.bpList, self.hardwareList, self.filterNameList, magList):

                FWHMeff = defaults.FWHMeff(filterName)

                m5 = snr.calcM5(self.skySed,
                                total,
                                hardware,
                                photParams,
                                FWHMeff=FWHMeff)

                sigma_sed = snr.calcMagError_sed(spectrum,
                                                 total,
                                                 self.skySed,
                                                 hardware,
                                                 photParams,
                                                 FWHMeff=FWHMeff)

                sigma_m5, gamma = snr.calcMagError_m5(mm, total, m5,
                                                      photParams)

                self.assertAlmostEqual(sigma_m5, sigma_sed, 3)
    def testMagDictForSed(self):
        """
        Test that magDictForSed calculates the correct magnitude
        """

        wavelen = numpy.arange(10.0,2000.0,1.0)
        flux = (wavelen*2.0-5.0)*1.0e-6
        spectrum = Sed(wavelen=wavelen, flambda=flux)

        for nBp in range(3, 10, 1):

            nameList, bpList = self.getListOfBandpasses(nBp)
            testDict = BandpassDict(bpList, nameList)
            self.assertFalse(len(testDict.values()[0].wavelen)==len(spectrum.wavelen))

            magDict = testDict.magDictForSed(spectrum)
            for ix, (name, bp) in enumerate(zip(nameList, bpList)):
                magControl = spectrum.calcMag(bp)
                self.assertAlmostEqual(magDict[name], magControl, 5)
예제 #29
0
def calcWDColors():
    """
    Calculate a few example WD colors. Values to go in stellarMags(). Here in case
    values need to be regenerated (different stars, bandpasses change, etc.)
    """

    try:
        from lsst.utils import getPackageDir
        import os
        from lsst.sims.photUtils import Bandpass, Sed
    except:
        'Need to setup sims_photUtils to generate WD magnitudes.'

    names = ['HeWD_25200_80', 'WD_11000_85', 'WD_3000_85']
    fns = [
        'bergeron_He_24000_80.dat_25200.gz', 'bergeron_10500_85.dat_11000.gz',
        'bergeron_2750_85.dat_3000.gz'
    ]
    wdDir = os.path.join(getPackageDir('sims_sed_library'), 'starSED/wDs/')
    files = [os.path.join(wdDir, filename) for filename in fns]

    # Read in the LSST bandpasses
    bpNames = ['u', 'g', 'r', 'i', 'z', 'y']
    bps = []
    throughPath = os.path.join(getPackageDir('throughputs'), 'baseline')
    for key in bpNames:
        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'])
        bps.append(tempB)

    # Read in the SEDs and compute mags
    mags = []
    for filename in files:
        star = Sed()
        star.readSED_flambda(filename)
        singleMags = [star.calcMag(band) for band in bps]
        mags.append([singleMags[i - 1] - singleMags[i] for i in range(1, 6)])

    for maglist, fn, name in zip(mags, fns, names):
        format = (name, fn) + tuple(maglist)
        print("['%s', '%s', %f, %f, %f, %f, %f]" % format)
예제 #30
0
    def computeMags(self, bandpass=None):
        """After the spectra have been computed, optionally convert to mags"""
        if self.mags:
            mags = -2.5*np.log10(self.spec)+np.log10(3631.)
        else:
            mags = np.zeros(self.npts, dtype=float)-666
            tempSed = Sed()
            isThrough = np.where(bandpass.sb > 0)
            minWave = bandpass.wavelen[isThrough].min()
            maxWave = bandpass.wavelen[isThrough].max()
            inBand = np.where( (self.wave >= minWave) & (self.wave <= maxWave))
            for i, ra in enumerate(self.ra):
                if np.max(self.spec[i,inBand]) > 0:
                    tempSed.setSED(self.wave, flambda=self.spec[i,:])
                    # Need to try/except because the spectra might be zero in the filter
                    # XXX-upgrade this to check if it's zero
                    mags[i] = tempSed.calcMag(bandpass)

        return mags
예제 #31
0
    def testMagDictForSed(self):
        """
        Test that magDictForSed calculates the correct magnitude
        """

        wavelen = numpy.arange(10.0,2000.0,1.0)
        flux = (wavelen*2.0-5.0)*1.0e-6
        spectrum = Sed(wavelen=wavelen, flambda=flux)

        for nBp in range(3, 10, 1):

            nameList, bpList = self.getListOfBandpasses(nBp)
            testDict = BandpassDict(bpList, nameList)
            self.assertFalse(len(testDict.values()[0].wavelen)==len(spectrum.wavelen))

            magDict = testDict.magDictForSed(spectrum)
            for ix, (name, bp) in enumerate(zip(nameList, bpList)):
                magControl = spectrum.calcMag(bp)
                self.assertAlmostEqual(magDict[name], magControl, 5)
예제 #32
0
    def computeMags(self, bandpass=None):
        """After the spectra have been computed, optionally convert to mags"""
        if self.mags:
            mags = -2.5 * np.log10(self.spec) + np.log10(3631.)
        else:
            mags = np.zeros(self.npts, dtype=float) - 666
            tempSed = Sed()
            isThrough = np.where(bandpass.sb > 0)
            minWave = bandpass.wavelen[isThrough].min()
            maxWave = bandpass.wavelen[isThrough].max()
            inBand = np.where((self.wave >= minWave) & (self.wave <= maxWave))
            for i, ra in enumerate(self.ra):
                if np.max(self.spec[i, inBand]) > 0:
                    tempSed.setSED(self.wave, flambda=self.spec[i, :])
                    # Need to try/except because the spectra might be zero in the filter
                    # XXX-upgrade this to check if it's zero
                    mags[i] = tempSed.calcMag(bandpass)

        return mags
예제 #33
0
    def testSignalToNoise(self):
        """
        Test that calcSNR_m5 and calcSNR_sed give similar results
        """
        defaults = LSSTdefaults()
        photParams = PhotometricParameters()

        m5 = []
        for i in range(len(self.hardwareList)):
            m5.append(
                snr.calcM5(self.skySed,
                           self.bpList[i],
                           self.hardwareList[i],
                           photParams,
                           FWHMeff=defaults.FWHMeff(self.filterNameList[i])))

        sedDir = os.path.join(lsst.utils.getPackageDir('sims_photUtils'),
                              'tests/cartoonSedTestData/starSed/')
        sedDir = os.path.join(sedDir, 'kurucz')
        fileNameList = os.listdir(sedDir)

        rng = np.random.RandomState(42)
        offset = rng.random_sample(len(fileNameList)) * 2.0

        for ix, name in enumerate(fileNameList):
            if ix > 100:
                break
            spectrum = Sed()
            spectrum.readSED_flambda(os.path.join(sedDir, name))
            ff = spectrum.calcFluxNorm(m5[2] - offset[ix], self.bpList[2])
            spectrum.multiplyFluxNorm(ff)
            for i in range(len(self.bpList)):
                control_snr = snr.calcSNR_sed(
                    spectrum, self.bpList[i], self.skySed,
                    self.hardwareList[i], photParams,
                    defaults.FWHMeff(self.filterNameList[i]))

                mag = spectrum.calcMag(self.bpList[i])

                test_snr, gamma = snr.calcSNR_m5(mag, self.bpList[i], m5[i],
                                                 photParams)
                self.assertLess((test_snr - control_snr) / control_snr, 0.001)
예제 #34
0
    def returnMags(self, bandpasses=None):
        """
        Convert the computed spectra to a magnitude using the supplied bandpass,
        or, if self.mags=True, return the mags in the LSST filters

        If mags=True when initialized, return mags returns an structured array with
        dtype names u,g,r,i,z,y.

        bandpasses: optional dictionary with bandpass name keys and bandpass object values.

        """
        if self.azs is None:
            raise ValueError('No coordinates set. Use setRaDecMjd, setRaDecAltAzMjd, or setParams methods before calling returnMags.')

        if self.mags:
            if bandpasses:
                warnings.warn('Ignoring set bandpasses and returning LSST ugrizy.')
            mags = -2.5*np.log10(self.spec)+np.log10(3631.)
            # Mask out high airmass
            mags[self.mask] *= np.nan
            mags = mags.swapaxes(0, 1)
            magsBack = {}
            for i, f in enumerate(self.filterNames):
                magsBack[f] = mags[i]
        else:
            magsBack = {}
            for key in bandpasses:
                mags = np.zeros(self.npts, dtype=float)-666
                tempSed = Sed()
                isThrough = np.where(bandpasses[key].sb > 0)
                minWave = bandpasses[key].wavelen[isThrough].min()
                maxWave = bandpasses[key].wavelen[isThrough].max()
                inBand = np.where((self.wave >= minWave) & (self.wave <= maxWave))
                for i, ra in enumerate(self.ra):
                    # Check that there is flux in the band, otherwise calcMag fails
                    if np.max(self.spec[i, inBand]) > 0:
                        tempSed.setSED(self.wave, flambda=self.spec[i, :])
                        mags[i] = tempSed.calcMag(bandpasses[key])
                # Mask out high airmass
                mags[self.mask] *= np.nan
                magsBack[key] = mags
        return magsBack
def _create_library_one_sed(_galaxy_sed_dir, sed_file_name_list, av_grid,
                            rv_grid, bandpass_dict, out_dict):

    n_obj = len(av_grid) * len(rv_grid)

    imsim_bp = Bandpass()
    imsim_bp.imsimBandpass()

    t_start = time.time()
    for i_sed, sed_file_name in enumerate(sed_file_name_list):
        if i_sed > 0 and i_sed % 10 == 0:
            duration = (time.time() - t_start) / 3600.0
            pred = len(sed_file_name_list) * duration / i_sed
            print('%d of %d; dur %.2e pred %.2e' %
                  (i_sed, len(sed_file_name_list), duration, pred))

        base_spec = Sed()
        base_spec.readSED_flambda(os.path.join(_galaxy_sed_dir, sed_file_name))
        ax, bx = base_spec.setupCCMab()

        mag_norm = base_spec.calcMag(imsim_bp)

        sed_names = np.array([defaultSpecMap[sed_file_name]] * n_obj)
        rv_out_list = np.zeros(n_obj, dtype=float)
        av_out_list = np.zeros(n_obj, dtype=float)
        sed_mag_norm = mag_norm * np.ones(n_obj, dtype=float)
        sed_mag_list = []

        i_obj = 0
        for av in av_grid:
            for rv in rv_grid:
                spec = Sed(wavelen=base_spec.wavelen,
                           flambda=base_spec.flambda)
                spec.addCCMDust(ax, bx, A_v=av, R_v=rv)
                av_out_list[i_obj] = av
                rv_out_list[i_obj] = rv
                sed_mag_list.append(tuple(bandpass_dict.magListForSed(spec)))
                i_obj += 1

        out_dict[sed_file_name] = (sed_names, sed_mag_norm, sed_mag_list,
                                   av_out_list, rv_out_list)
예제 #36
0
def calcWDColors():
    """
    Calculate a few example WD colors. Values to go in stellarMags(). Here in case
    values need to be regenerated (different stars, bandpasses change, etc.)
    """

    try:
        from lsst.utils import getPackageDir
        import os
        from lsst.sims.photUtils import Bandpass, Sed
    except:
        'Need to setup sims_photUtils to generate WD magnitudes.'

    names = ['HeWD_25200_80', 'WD_11000_85', 'WD_3000_85']
    fns = ['bergeron_He_24000_80.dat_25200.gz',
           'bergeron_10500_85.dat_11000.gz', 'bergeron_2750_85.dat_3000.gz']
    wdDir = os.path.join(getPackageDir('sims_sed_library'), 'starSED/wDs/')
    files = [os.path.join(wdDir, filename) for filename in fns]

    # Read in the LSST bandpasses
    bpNames = ['u', 'g', 'r', 'i', 'z', 'y']
    bps = []
    throughPath = os.path.join(getPackageDir('throughputs'), 'baseline')
    for key in bpNames:
        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'])
        bps.append(tempB)

    # Read in the SEDs and compute mags
    mags = []
    for filename in files:
        star = Sed()
        star.readSED_flambda(filename)
        singleMags = [star.calcMag(band) for band in bps]
        mags.append([singleMags[i - 1] - singleMags[i] for i in range(1, 6)])

    for maglist, fn, name in zip(mags, fns, names):
        format = (name, fn) + tuple(maglist)
        print("['%s', '%s', %f, %f, %f, %f, %f]" % format)
예제 #37
0
    def testMagError(self):
        """
        Make sure that calcMagError_sed and calcMagError_m5
        agree to within 0.001
        """
        defaults = LSSTdefaults()
        photParams = PhotometricParameters()

        #create a cartoon spectrum to test on
        spectrum = Sed()
        spectrum.setFlatSED()
        spectrum.multiplyFluxNorm(1.0e-9)

        #find the magnitudes of that spectrum in our bandpasses
        magList = []
        for total in self.bpList:
            magList.append(spectrum.calcMag(total))
        magList = numpy.array(magList)

        #try for different normalizations of the skySED
        for fNorm in numpy.arange(1.0, 5.0, 1.0):
            self.skySed.multiplyFluxNorm(fNorm)
            m5List = []
            magSed = []
            for total, hardware, filterName in \
            zip(self.bpList, self.hardwareList, self.filterNameList):

                seeing = defaults.seeing(filterName)

                m5List.append(snr.calcM5(self.skySed, total, hardware, photParams,seeing=seeing))

                magSed.append(snr.calcMagError_sed(spectrum, total, self.skySed,
                                                   hardware, photParams, seeing=seeing))

            magSed = numpy.array(magSed)

            magM5 = snr.calcMagError_m5(magList, self.bpList,
                                        numpy.array(m5List), photParams)


            numpy.testing.assert_array_almost_equal(magM5, magSed, decimal=3)
예제 #38
0
    def testSignalToNoise(self):
        """
        Test that calcSNR_m5 and calcSNR_sed give similar results
        """
        defaults = LSSTdefaults()
        photParams = PhotometricParameters()

        m5 = []
        for i in range(len(self.hardwareList)):
            m5.append(snr.calcM5(self.skySed, self.bpList[i],
                      self.hardwareList[i],
                      photParams, FWHMeff=defaults.FWHMeff(self.filterNameList[i])))

        sedDir = os.path.join(lsst.utils.getPackageDir('sims_photUtils'),
                              'tests/cartoonSedTestData/starSed/')
        sedDir = os.path.join(sedDir, 'kurucz')
        fileNameList = os.listdir(sedDir)

        rng = np.random.RandomState(42)
        offset = rng.random_sample(len(fileNameList))*2.0

        for ix, name in enumerate(fileNameList):
            if ix > 100:
                break
            spectrum = Sed()
            spectrum.readSED_flambda(os.path.join(sedDir, name))
            ff = spectrum.calcFluxNorm(m5[2]-offset[ix], self.bpList[2])
            spectrum.multiplyFluxNorm(ff)
            for i in range(len(self.bpList)):
                control_snr = snr.calcSNR_sed(spectrum, self.bpList[i],
                                              self.skySed,
                                              self.hardwareList[i],
                                              photParams, defaults.FWHMeff(self.filterNameList[i]))

                mag = spectrum.calcMag(self.bpList[i])

                test_snr, gamma = snr.calcSNR_m5(mag, self.bpList[i], m5[i], photParams)
                self.assertLess((test_snr-control_snr)/control_snr, 0.001)
예제 #39
0
    def testMagError(self):
        """
        Make sure that calcMagError_sed and calcMagError_m5
        agree to within 0.001
        """
        defaults = LSSTdefaults()
        photParams = PhotometricParameters()

        # create a cartoon spectrum to test on
        spectrum = Sed()
        spectrum.setFlatSED()
        spectrum.multiplyFluxNorm(1.0e-9)

        # find the magnitudes of that spectrum in our bandpasses
        magList = []
        for total in self.bpList:
            magList.append(spectrum.calcMag(total))
        magList = numpy.array(magList)

        # try for different normalizations of the skySED
        for fNorm in numpy.arange(1.0, 5.0, 1.0):
            self.skySed.multiplyFluxNorm(fNorm)
            m5List = []
            magSed = []
            for total, hardware, filterName in zip(self.bpList, self.hardwareList, self.filterNameList):

                seeing = defaults.seeing(filterName)

                m5List.append(snr.calcM5(self.skySed, total, hardware, photParams, seeing=seeing))

                magSed.append(snr.calcMagError_sed(spectrum, total, self.skySed, hardware, photParams, seeing=seeing))

            magSed = numpy.array(magSed)

            magM5 = snr.calcMagError_m5(magList, self.bpList, numpy.array(m5List), photParams)

            numpy.testing.assert_array_almost_equal(magM5, magSed, decimal=3)
예제 #40
0
 def testSedMagErrors(self):
     """Test error handling at mag and adu calculation levels of sed."""
     sedwavelen = np.arange(self.wmin + 50, self.wmax, 1)
     sedflambda = np.ones(len(sedwavelen))
     testsed = Sed(wavelen=sedwavelen, flambda=sedflambda)
     # Test handling in calcMag
     with warnings.catch_warnings(record=True) as w:
         mag = testsed.calcMag(self.testbandpass)
         self.assertEqual(len(w), 1)
         self.assertIn("non-overlap", str(w[-1].message))
     np.testing.assert_equal(mag, np.NaN)
     # Test handling in calcADU
     with warnings.catch_warnings(record=True) as w:
         adu = testsed.calcADU(self.testbandpass,
                               photParams=PhotometricParameters())
         self.assertEqual(len(w), 1)
         self.assertIn("non-overlap", str(w[-1].message))
     np.testing.assert_equal(adu, np.NaN)
     # Test handling in calcFlux
     with warnings.catch_warnings(record=True) as w:
         flux = testsed.calcFlux(self.testbandpass)
         self.assertEqual(len(w), 1)
         self.assertIn("non-overlap", str(w[-1].message))
     np.testing.assert_equal(flux, np.NaN)
예제 #41
0
 def testSedMagErrors(self):
     """Test error handling at mag and adu calculation levels of sed."""
     sedwavelen = np.arange(self.wmin+50, self.wmax, 1)
     sedflambda = np.ones(len(sedwavelen))
     testsed = Sed(wavelen=sedwavelen, flambda=sedflambda)
     # Test handling in calcMag
     with warnings.catch_warnings(record=True) as w:
         mag = testsed.calcMag(self.testbandpass)
         self.assertEqual(len(w), 1)
         self.assertIn("non-overlap", str(w[-1].message))
     np.testing.assert_equal(mag, np.NaN)
     # Test handling in calcADU
     with warnings.catch_warnings(record=True) as w:
         adu = testsed.calcADU(self.testbandpass,
                               photParams=PhotometricParameters())
         self.assertEqual(len(w), 1)
         self.assertIn("non-overlap", str(w[-1].message))
     np.testing.assert_equal(adu, np.NaN)
     # Test handling in calcFlux
     with warnings.catch_warnings(record=True) as w:
         flux = testsed.calcFlux(self.testbandpass)
         self.assertEqual(len(w), 1)
         self.assertIn("non-overlap", str(w[-1].message))
     np.testing.assert_equal(flux, np.NaN)
예제 #42
0
    def testMagError(self):
        """
        Make sure that calcMagError_sed and calcMagError_m5
        agree to within 0.001
        """
        defaults = LSSTdefaults()
        photParams = PhotometricParameters()

        # create a cartoon spectrum to test on
        spectrum = Sed()
        spectrum.setFlatSED()
        spectrum.multiplyFluxNorm(1.0e-9)

        # find the magnitudes of that spectrum in our bandpasses
        magList = []
        for total in self.bpList:
            magList.append(spectrum.calcMag(total))
        magList = np.array(magList)

        # try for different normalizations of the skySED
        for fNorm in np.arange(1.0, 5.0, 1.0):
            self.skySed.multiplyFluxNorm(fNorm)

            for total, hardware, filterName, mm in \
                zip(self.bpList, self.hardwareList, self.filterNameList, magList):

                FWHMeff = defaults.FWHMeff(filterName)

                m5 = snr.calcM5(self.skySed, total, hardware, photParams, FWHMeff=FWHMeff)

                sigma_sed = snr.calcMagError_sed(spectrum, total, self.skySed,
                                                 hardware, photParams, FWHMeff=FWHMeff)

                sigma_m5, gamma = snr.calcMagError_m5(mm, total, m5, photParams)

                self.assertAlmostEqual(sigma_m5, sigma_sed, 3)
def packageMoon():
    dataDir = getPackageDir('SIMS_SKYBRIGHTNESS_DATA')
    outDir = os.path.join(dataDir, 'ESO_Spectra/Moon')

    # Read in all the spectra from ESO call and package into a single npz file

    files = glob.glob('Moon/skytable*.fits')

    temp = pyfits.open(files[0])
    moonWave = temp[1].data['lam'].copy()*1e3

    moonSpec = []
    moonAM = [] # Actually target airmass
    moonAlt=[]  # altitude of the moon
    moonSunSep=[] # moon Phase
    moonTargetSep=[]
    hpid=[]
    for i,filename in enumerate(files):
        fits = pyfits.open(filename)
        try:
            if np.max(fits[1].data['flux']) > 0:
                moonSpec.append(fits[1].data['flux'].copy())
                header = fits[0].header['comment']
                for card in header:
                    if 'SKYMODEL.MOON.SUN.SEP' in card:
                        moonSunSep.append(float(card.split('=')[-1]))
                    elif 'SKYMODEL.TARGET.AIRMASS' in card:
                        #moonAM.append( 1./np.cos(np.radians(90.-float(card.split('=')[-1]))) )
                        moonAM.append( float(card.split('=')[-1]) )
                    elif 'SKYMODEL.MOON.TARGET.SEP' in card:
                        moonTargetSep.append(float(card.split('=')[-1]))
                    elif 'SKYMODEL.MOON.ALT' in card:
                        moonAlt.append(float(card.split('=')[-1]))
        except:
            print filename, ' Failed'

    import healpy as hp
    from lsst.sims.utils import haversine

    nside = 4
    lat, az = hp.pix2ang(nside, np.arange(hp.nside2npix(nside)))
    alt = np.pi/2.-lat
    airmass = 1./np.cos(np.pi/2.-alt)

    # Only need low airmass and then 1/2 to sky
    good = np.where( (az >= 0) & (az <= np.pi) & (airmass <=2.6) & (airmass >= 1.) )
    airmass = airmass[good]
    alt=alt[good]
    az = az[good]

    moonAM = np.array(moonAM)
    moonAlt = np.array(moonAlt)
    moonSunSep = np.array(moonSunSep)
    moonTargetSep = np.array(moonTargetSep)
    moonAzDiff = moonTargetSep*0
    targetAlt = np.pi/2.-np.arccos(1./moonAM)
    # Compute the azimuth difference given the moon-target-seperation
    # Let's just do a stupid loop:
    for i in np.arange(targetAlt.size):
        possibleDistances = haversine(0., np.radians(moonAlt[i]),  az, az*0+targetAlt[i])
        diff = np.abs(possibleDistances - np.radians(moonTargetSep[i]))
        good = np.where(diff == diff.min())
        moonAzDiff[i] = az[good][0]
        # ok, now I have an alt and az, I can convert that back to a healpix id.

        hpid.append(hp.ang2pix(nside, np.pi/2.-targetAlt[i], moonAzDiff[i]))

    nrec = moonAM.size
    nwave = moonWave.size

    dtype = [('hpid', 'int'),
             ('moonAltitude', 'float'),
             ('moonSunSep', 'float'),
             ('spectra', 'float', (nwave)), ('mags', 'float', (6))]
    moonSpectra = np.zeros(nrec, dtype=dtype)
    moonSpectra['hpid'] = hpid
    moonSpectra['moonAltitude'] = moonAlt
    moonSpectra['moonSunSep'] = moonSunSep
    moonSpectra['spectra'] = moonSpec

    hPlank = 6.626068e-27  # erg s
    cLight = 2.99792458e10 # cm/s

    # Convert spectra from ph/s/m2/micron/arcsec2 to erg/s/cm2/nm/arcsec2
    moonSpectra['spectra'] = moonSpectra['spectra']/(100.**2)*hPlank*cLight/(moonWave*1e-7)/1e3

    # Sort things since this might be helpful later
    moonSpectra.sort(order=['moonSunSep','moonAltitude', 'hpid'])

    # Crop off the incomplete ones

    good =np.where((moonSpectra['moonAltitude'] >= 0) & (moonSpectra['moonAltitude'] < 89.) )
    moonSpectra = moonSpectra[good]

    # Load LSST filters
    throughPath = os.path.join(getPackageDir('throughputs'),'baseline')
    keys = ['u','g','r','i','z','y']
    nfilt = len(keys)
    filters = {}
    for filtername in keys:
        bp = np.loadtxt(os.path.join(throughPath, 'filter_'+filtername+'.dat'),
                        dtype=zip(['wave','trans'],[float]*2 ))
        tempB = Bandpass()
        tempB.setBandpass(bp['wave'],bp['trans'])
        filters[filtername] = tempB

    filterWave = np.array([filters[f].calcEffWavelen()[0] for f in keys ])

    for i,spectrum in enumerate(moonSpectra['spectra']):
        tempSed = Sed()
        tempSed.setSED(moonWave,flambda=spectrum)
        for j,filtName in enumerate(keys):
            try:
                moonSpectra['mags'][i][j] = tempSed.calcMag(filters[filtName])
            except:
                pass

    nbreak=5
    nrec = np.size(moonSpectra)
    for i in np.arange(nbreak):
        np.savez(os.path.join(outDir,'moonSpectra_'+str(i)+'.npz'), wave = moonWave, spec=moonSpectra[i*nrec/nbreak:(i+1)*nrec/nbreak], filterWave=filterWave)
예제 #44
0
class TestSNRmethods(unittest.TestCase):
    def setUp(self):

        starFileName = os.path.join(lsst.utils.getPackageDir("sims_sed_library"), "starSED")
        starFileName = os.path.join(starFileName, "kurucz", "km20_5750.fits_g40_5790.gz")
        starName = os.path.join(lsst.utils.getPackageDir("sims_sed_library"), starFileName)
        self.starSED = Sed()
        self.starSED.readSED_flambda(starName)
        imsimband = Bandpass()
        imsimband.imsimBandpass()
        fNorm = self.starSED.calcFluxNorm(22.0, imsimband)
        self.starSED.multiplyFluxNorm(fNorm)

        hardwareDir = os.path.join(lsst.utils.getPackageDir("throughputs"), "baseline")
        componentList = ["detector.dat", "m1.dat", "m2.dat", "m3.dat", "lens1.dat", "lens2.dat", "lens3.dat"]
        self.skySed = Sed()
        self.skySed.readSED_flambda(os.path.join(hardwareDir, "darksky.dat"))

        totalNameList = ["total_u.dat", "total_g.dat", "total_r.dat", "total_i.dat", "total_z.dat", "total_y.dat"]

        self.bpList = []
        self.hardwareList = []
        for name in totalNameList:
            dummy = Bandpass()
            dummy.readThroughput(os.path.join(hardwareDir, name))
            self.bpList.append(dummy)

            dummy = Bandpass()
            hardwareNameList = [os.path.join(hardwareDir, name)]
            for component in componentList:
                hardwareNameList.append(os.path.join(hardwareDir, component))
            dummy.readThroughputList(hardwareNameList)
            self.hardwareList.append(dummy)

        self.filterNameList = ["u", "g", "r", "i", "z", "y"]

    def testMagError(self):
        """
        Make sure that calcMagError_sed and calcMagError_m5
        agree to within 0.001
        """
        defaults = LSSTdefaults()
        photParams = PhotometricParameters()

        # create a cartoon spectrum to test on
        spectrum = Sed()
        spectrum.setFlatSED()
        spectrum.multiplyFluxNorm(1.0e-9)

        # find the magnitudes of that spectrum in our bandpasses
        magList = []
        for total in self.bpList:
            magList.append(spectrum.calcMag(total))
        magList = numpy.array(magList)

        # try for different normalizations of the skySED
        for fNorm in numpy.arange(1.0, 5.0, 1.0):
            self.skySed.multiplyFluxNorm(fNorm)
            m5List = []
            magSed = []
            for total, hardware, filterName in zip(self.bpList, self.hardwareList, self.filterNameList):

                seeing = defaults.seeing(filterName)

                m5List.append(snr.calcM5(self.skySed, total, hardware, photParams, seeing=seeing))

                magSed.append(snr.calcMagError_sed(spectrum, total, self.skySed, hardware, photParams, seeing=seeing))

            magSed = numpy.array(magSed)

            magM5 = snr.calcMagError_m5(magList, self.bpList, numpy.array(m5List), photParams)

            numpy.testing.assert_array_almost_equal(magM5, magSed, decimal=3)

    def testVerboseSNR(self):
        """
        Make sure that calcSNR_sed has everything it needs to run in verbose mode
        """
        defaults = LSSTdefaults()
        photParams = PhotometricParameters()

        # create a cartoon spectrum to test on
        spectrum = Sed()
        spectrum.setFlatSED()
        spectrum.multiplyFluxNorm(1.0e-9)

        snr.calcSNR_sed(
            spectrum, self.bpList[0], self.skySed, self.hardwareList[0], photParams, seeing=0.7, verbose=True
        )

    def testSNRexceptions(self):
        """
        test that calcSNR_m5 raises an exception when arguments are not of the right shape.
        """

        photParams = PhotometricParameters()
        shortGamma = numpy.array([1.0, 1.0])
        shortMagnitudes = numpy.array([22.0, 23.0])
        magnitudes = 22.0 * numpy.ones(6)
        self.assertRaises(RuntimeError, snr.calcSNR_m5, magnitudes, self.bpList, shortMagnitudes, photParams)
        self.assertRaises(RuntimeError, snr.calcSNR_m5, shortMagnitudes, self.bpList, magnitudes, photParams)
        self.assertRaises(
            RuntimeError, snr.calcSNR_m5, magnitudes, self.bpList, magnitudes, photParams, gamma=shortGamma
        )
        signalToNoise, gg = snr.calcSNR_m5(magnitudes, self.bpList, magnitudes, photParams)

    def testSignalToNoise(self):
        """
        Test that calcSNR_m5 and calcSNR_sed give similar results
        """
        defaults = LSSTdefaults()
        photParams = PhotometricParameters()

        m5 = []
        for i in range(len(self.hardwareList)):
            m5.append(
                snr.calcM5(
                    self.skySed,
                    self.bpList[i],
                    self.hardwareList[i],
                    photParams,
                    seeing=defaults.seeing(self.filterNameList[i]),
                )
            )

        sedDir = lsst.utils.getPackageDir("sims_sed_library")
        sedDir = os.path.join(sedDir, "starSED", "kurucz")
        fileNameList = os.listdir(sedDir)

        numpy.random.seed(42)
        offset = numpy.random.random_sample(len(fileNameList)) * 2.0

        for ix, name in enumerate(fileNameList):
            if ix > 100:
                break
            spectrum = Sed()
            spectrum.readSED_flambda(os.path.join(sedDir, name))
            ff = spectrum.calcFluxNorm(m5[2] - offset[ix], self.bpList[2])
            spectrum.multiplyFluxNorm(ff)
            magList = []
            controlList = []
            magList = []
            for i in range(len(self.bpList)):
                controlList.append(
                    snr.calcSNR_sed(
                        spectrum,
                        self.bpList[i],
                        self.skySed,
                        self.hardwareList[i],
                        photParams,
                        defaults.seeing(self.filterNameList[i]),
                    )
                )

                magList.append(spectrum.calcMag(self.bpList[i]))

            testList, gammaList = snr.calcSNR_m5(
                numpy.array(magList), numpy.array(self.bpList), numpy.array(m5), photParams
            )

            for tt, cc in zip(controlList, testList):
                msg = "%e != %e " % (tt, cc)
                self.assertTrue(numpy.abs(tt / cc - 1.0) < 0.001, msg=msg)

    def testSystematicUncertainty(self):
        """
        Test that systematic uncertainty is added correctly.
        """
        sigmaSys = 0.002
        m5 = [23.5, 24.3, 22.1, 20.0, 19.5, 21.7]
        photParams = PhotometricParameters(sigmaSys=sigmaSys)

        obs_metadata = ObservationMetaData(
            unrefractedRA=23.0, unrefractedDec=45.0, m5=m5, bandpassName=self.filterNameList
        )
        magnitudes = []
        for bp in self.bpList:
            mag = self.starSED.calcMag(bp)
            magnitudes.append(mag)

        skySedList = []

        for bp, hardware, filterName in zip(self.bpList, self.hardwareList, self.filterNameList):
            skyDummy = Sed()
            skyDummy.readSED_flambda(os.path.join(lsst.utils.getPackageDir("throughputs"), "baseline", "darksky.dat"))
            normalizedSkyDummy = setM5(
                obs_metadata.m5[filterName],
                skyDummy,
                bp,
                hardware,
                seeing=LSSTdefaults().seeing(filterName),
                photParams=photParams,
            )

            skySedList.append(normalizedSkyDummy)

        sigmaList = snr.calcMagError_m5(numpy.array(magnitudes), numpy.array(self.bpList), numpy.array(m5), photParams)

        for i in range(len(self.bpList)):
            snrat = snr.calcSNR_sed(
                self.starSED,
                self.bpList[i],
                skySedList[i],
                self.hardwareList[i],
                seeing=LSSTdefaults().seeing(self.filterNameList[i]),
                photParams=PhotometricParameters(),
            )

            testSNR, gamma = snr.calcSNR_m5(
                numpy.array([magnitudes[i]]),
                [self.bpList[i]],
                numpy.array([m5[i]]),
                photParams=PhotometricParameters(sigmaSys=0.0),
            )

            self.assertAlmostEqual(
                snrat, testSNR[0], 10, msg="failed on calcSNR_m5 test %e != %e " % (snrat, testSNR[0])
            )

            control = numpy.sqrt(numpy.power(snr.magErrorFromSNR(testSNR), 2) + numpy.power(sigmaSys, 2))

            msg = "%e is not %e; failed" % (sigmaList[i], control)

            self.assertAlmostEqual(sigmaList[i], control, 10, msg=msg)

    def testNoSystematicUncertainty(self):
        """
        Test that systematic uncertainty is handled correctly when set to None.
        """
        m5 = [23.5, 24.3, 22.1, 20.0, 19.5, 21.7]
        photParams = PhotometricParameters(sigmaSys=0.0)

        obs_metadata = ObservationMetaData(
            unrefractedRA=23.0, unrefractedDec=45.0, m5=m5, bandpassName=self.filterNameList
        )

        magnitudes = []
        for bp in self.bpList:
            mag = self.starSED.calcMag(bp)
            magnitudes.append(mag)

        skySedList = []

        for bp, hardware, filterName in zip(self.bpList, self.hardwareList, self.filterNameList):
            skyDummy = Sed()
            skyDummy.readSED_flambda(os.path.join(lsst.utils.getPackageDir("throughputs"), "baseline", "darksky.dat"))
            normalizedSkyDummy = setM5(
                obs_metadata.m5[filterName],
                skyDummy,
                bp,
                hardware,
                seeing=LSSTdefaults().seeing(filterName),
                photParams=photParams,
            )

            skySedList.append(normalizedSkyDummy)

        sigmaList = snr.calcMagError_m5(numpy.array(magnitudes), numpy.array(self.bpList), numpy.array(m5), photParams)

        for i in range(len(self.bpList)):
            snrat = snr.calcSNR_sed(
                self.starSED,
                self.bpList[i],
                skySedList[i],
                self.hardwareList[i],
                seeing=LSSTdefaults().seeing(self.filterNameList[i]),
                photParams=PhotometricParameters(),
            )

            testSNR, gamma = snr.calcSNR_m5(
                numpy.array([magnitudes[i]]),
                [self.bpList[i]],
                numpy.array([m5[i]]),
                photParams=PhotometricParameters(sigmaSys=0.0),
            )

            self.assertAlmostEqual(
                snrat, testSNR[0], 10, msg="failed on calcSNR_m5 test %e != %e " % (snrat, testSNR[0])
            )

            control = snr.magErrorFromSNR(testSNR)

            msg = "%e is not %e; failed" % (sigmaList[i], control)

            self.assertAlmostEqual(sigmaList[i], control, 10, msg=msg)
예제 #45
0
class TestSNRmethods(unittest.TestCase):
    def setUp(self):

        starName = os.path.join(lsst.utils.getPackageDir('sims_photUtils'),
                                'tests/cartoonSedTestData/starSed/')
        starName = os.path.join(starName, 'kurucz',
                                'km20_5750.fits_g40_5790.gz')
        self.starSED = Sed()
        self.starSED.readSED_flambda(starName)
        imsimband = Bandpass()
        imsimband.imsimBandpass()
        fNorm = self.starSED.calcFluxNorm(22.0, imsimband)
        self.starSED.multiplyFluxNorm(fNorm)

        hardwareDir = os.path.join(lsst.utils.getPackageDir('throughputs'),
                                   'baseline')
        componentList = [
            'detector.dat', 'm1.dat', 'm2.dat', 'm3.dat', 'lens1.dat',
            'lens2.dat', 'lens3.dat'
        ]
        self.skySed = Sed()
        self.skySed.readSED_flambda(os.path.join(hardwareDir, 'darksky.dat'))

        totalNameList = [
            'total_u.dat', 'total_g.dat', 'total_r.dat', 'total_i.dat',
            'total_z.dat', 'total_y.dat'
        ]

        self.bpList = []
        self.hardwareList = []
        for name in totalNameList:
            dummy = Bandpass()
            dummy.readThroughput(os.path.join(hardwareDir, name))
            self.bpList.append(dummy)

            dummy = Bandpass()
            hardwareNameList = [os.path.join(hardwareDir, name)]
            for component in componentList:
                hardwareNameList.append(os.path.join(hardwareDir, component))
            dummy.readThroughputList(hardwareNameList)
            self.hardwareList.append(dummy)

        self.filterNameList = ['u', 'g', 'r', 'i', 'z', 'y']

    def testMagError(self):
        """
        Make sure that calcMagError_sed and calcMagError_m5
        agree to within 0.001
        """
        defaults = LSSTdefaults()
        photParams = PhotometricParameters()

        # create a cartoon spectrum to test on
        spectrum = Sed()
        spectrum.setFlatSED()
        spectrum.multiplyFluxNorm(1.0e-9)

        # find the magnitudes of that spectrum in our bandpasses
        magList = []
        for total in self.bpList:
            magList.append(spectrum.calcMag(total))
        magList = np.array(magList)

        # try for different normalizations of the skySED
        for fNorm in np.arange(1.0, 5.0, 1.0):
            self.skySed.multiplyFluxNorm(fNorm)

            for total, hardware, filterName, mm in \
                zip(self.bpList, self.hardwareList, self.filterNameList, magList):

                FWHMeff = defaults.FWHMeff(filterName)

                m5 = snr.calcM5(self.skySed,
                                total,
                                hardware,
                                photParams,
                                FWHMeff=FWHMeff)

                sigma_sed = snr.calcMagError_sed(spectrum,
                                                 total,
                                                 self.skySed,
                                                 hardware,
                                                 photParams,
                                                 FWHMeff=FWHMeff)

                sigma_m5, gamma = snr.calcMagError_m5(mm, total, m5,
                                                      photParams)

                self.assertAlmostEqual(sigma_m5, sigma_sed, 3)

    def testVerboseSNR(self):
        """
        Make sure that calcSNR_sed has everything it needs to run in verbose mode
        """
        photParams = PhotometricParameters()

        # create a cartoon spectrum to test on
        spectrum = Sed()
        spectrum.setFlatSED()
        spectrum.multiplyFluxNorm(1.0e-9)

        snr.calcSNR_sed(spectrum,
                        self.bpList[0],
                        self.skySed,
                        self.hardwareList[0],
                        photParams,
                        FWHMeff=0.7,
                        verbose=True)

    def testSignalToNoise(self):
        """
        Test that calcSNR_m5 and calcSNR_sed give similar results
        """
        defaults = LSSTdefaults()
        photParams = PhotometricParameters()

        m5 = []
        for i in range(len(self.hardwareList)):
            m5.append(
                snr.calcM5(self.skySed,
                           self.bpList[i],
                           self.hardwareList[i],
                           photParams,
                           FWHMeff=defaults.FWHMeff(self.filterNameList[i])))

        sedDir = os.path.join(lsst.utils.getPackageDir('sims_photUtils'),
                              'tests/cartoonSedTestData/starSed/')
        sedDir = os.path.join(sedDir, 'kurucz')
        fileNameList = os.listdir(sedDir)

        rng = np.random.RandomState(42)
        offset = rng.random_sample(len(fileNameList)) * 2.0

        for ix, name in enumerate(fileNameList):
            if ix > 100:
                break
            spectrum = Sed()
            spectrum.readSED_flambda(os.path.join(sedDir, name))
            ff = spectrum.calcFluxNorm(m5[2] - offset[ix], self.bpList[2])
            spectrum.multiplyFluxNorm(ff)
            for i in range(len(self.bpList)):
                control_snr = snr.calcSNR_sed(
                    spectrum, self.bpList[i], self.skySed,
                    self.hardwareList[i], photParams,
                    defaults.FWHMeff(self.filterNameList[i]))

                mag = spectrum.calcMag(self.bpList[i])

                test_snr, gamma = snr.calcSNR_m5(mag, self.bpList[i], m5[i],
                                                 photParams)
                self.assertLess((test_snr - control_snr) / control_snr, 0.001)

    def testSystematicUncertainty(self):
        """
        Test that systematic uncertainty is added correctly.
        """
        sigmaSys = 0.002
        m5_list = [23.5, 24.3, 22.1, 20.0, 19.5, 21.7]
        photParams = PhotometricParameters(sigmaSys=sigmaSys)

        obs_metadata = ObservationMetaData(pointingRA=23.0,
                                           pointingDec=45.0,
                                           m5=m5_list,
                                           bandpassName=self.filterNameList)
        magnitude_list = []
        for bp in self.bpList:
            mag = self.starSED.calcMag(bp)
            magnitude_list.append(mag)

        for bp, hardware, filterName, mm, m5 in \
            zip(self.bpList, self.hardwareList, self.filterNameList, magnitude_list, m5_list):

            skyDummy = Sed()
            skyDummy.readSED_flambda(
                os.path.join(lsst.utils.getPackageDir('throughputs'),
                             'baseline', 'darksky.dat'))

            normalizedSkyDummy = setM5(
                obs_metadata.m5[filterName],
                skyDummy,
                bp,
                hardware,
                FWHMeff=LSSTdefaults().FWHMeff(filterName),
                photParams=photParams)

            sigma, gamma = snr.calcMagError_m5(mm, bp, m5, photParams)

            snrat = snr.calcSNR_sed(self.starSED,
                                    bp,
                                    normalizedSkyDummy,
                                    hardware,
                                    FWHMeff=LSSTdefaults().FWHMeff(filterName),
                                    photParams=PhotometricParameters())

            testSNR, gamma = snr.calcSNR_m5(
                mm, bp, m5, photParams=PhotometricParameters(sigmaSys=0.0))

            self.assertAlmostEqual(snrat,
                                   testSNR,
                                   10,
                                   msg='failed on calcSNR_m5 test %e != %e ' %
                                   (snrat, testSNR))

            control = np.sqrt(
                np.power(snr.magErrorFromSNR(testSNR), 2) +
                np.power(sigmaSys, 2))

            msg = '%e is not %e; failed' % (sigma, control)

            self.assertAlmostEqual(sigma, control, 10, msg=msg)

    def testNoSystematicUncertainty(self):
        """
        Test that systematic uncertainty is handled correctly when set to None.
        """
        m5_list = [23.5, 24.3, 22.1, 20.0, 19.5, 21.7]
        photParams = PhotometricParameters(sigmaSys=0.0)

        obs_metadata = ObservationMetaData(pointingRA=23.0,
                                           pointingDec=45.0,
                                           m5=m5_list,
                                           bandpassName=self.filterNameList)

        magnitude_list = []
        for bp in self.bpList:
            mag = self.starSED.calcMag(bp)
            magnitude_list.append(mag)

        for bp, hardware, filterName, mm, m5 in \
            zip(self.bpList, self.hardwareList, self.filterNameList, magnitude_list, m5_list):

            skyDummy = Sed()
            skyDummy.readSED_flambda(
                os.path.join(lsst.utils.getPackageDir('throughputs'),
                             'baseline', 'darksky.dat'))

            normalizedSkyDummy = setM5(
                obs_metadata.m5[filterName],
                skyDummy,
                bp,
                hardware,
                FWHMeff=LSSTdefaults().FWHMeff(filterName),
                photParams=photParams)

            sigma, gamma = snr.calcMagError_m5(mm, bp, m5, photParams)

            snrat = snr.calcSNR_sed(self.starSED,
                                    bp,
                                    normalizedSkyDummy,
                                    hardware,
                                    FWHMeff=LSSTdefaults().FWHMeff(filterName),
                                    photParams=PhotometricParameters())

            testSNR, gamma = snr.calcSNR_m5(
                mm, bp, m5, photParams=PhotometricParameters(sigmaSys=0.0))

            self.assertAlmostEqual(snrat,
                                   testSNR,
                                   10,
                                   msg='failed on calcSNR_m5 test %e != %e ' %
                                   (snrat, testSNR))

            control = snr.magErrorFromSNR(testSNR)

            msg = '%e is not %e; failed' % (sigma, control)

            self.assertAlmostEqual(sigma, control, 10, msg=msg)

    def testFWHMconversions(self):
        FWHMeff = 0.8
        FWHMgeom = snr.FWHMeff2FWHMgeom(FWHMeff)
        self.assertEqual(FWHMgeom, (0.822 * FWHMeff + 0.052))
        FWHMgeom = 0.8
        FWHMeff = snr.FWHMgeom2FWHMeff(FWHMgeom)
        self.assertEqual(FWHMeff, (FWHMgeom - 0.052) / 0.822)

    def testSNR_arr(self):
        """
        Test that calcSNR_m5 works on numpy arrays of magnitudes
        """
        rng = np.random.RandomState(17)
        mag_list = rng.random_sample(100) * 5.0 + 15.0

        photParams = PhotometricParameters()
        bp = self.bpList[0]
        m5 = 24.0
        control_list = []
        for mm in mag_list:
            ratio, gamma = snr.calcSNR_m5(mm, bp, m5, photParams)
            control_list.append(ratio)
        control_list = np.array(control_list)

        test_list, gamma = snr.calcSNR_m5(mag_list, bp, m5, photParams)

        np.testing.assert_array_equal(control_list, test_list)

    def testError_arr(self):
        """
        Test that calcMagError_m5 works on numpy arrays of magnitudes
        """
        rng = np.random.RandomState(17)
        mag_list = rng.random_sample(100) * 5.0 + 15.0

        photParams = PhotometricParameters()
        bp = self.bpList[0]
        m5 = 24.0
        control_list = []
        for mm in mag_list:
            sig, gamma = snr.calcMagError_m5(mm, bp, m5, photParams)
            control_list.append(sig)
        control_list = np.array(control_list)

        test_list, gamma = snr.calcMagError_m5(mag_list, bp, m5, photParams)

        np.testing.assert_array_equal(control_list, test_list)
# create the a,b arrays for all the gals (because we resampled the gals onto the
#  same wavelength range we can just calculate a/b once, and this is slow)

a_gal, b_gal = gals[galaxykeys[0]].setupCCMab()

# pretend we want to read mags into an array .. you could just as easily put it into a
# dictionary or list, with small variations in the code
mags = n.empty(len(galaxykeys), dtype='float')

for i in range(len(galaxykeys)):
    # make a copy of the original SED if you want to 'reuse' the SED for multiple magnitude
    # calculations with various fluxnorms, redshifts and dusts
    tmpgal = Sed(wavelen=gals[galaxykeys[i]].wavelen, flambda=gals[galaxykeys[i]].flambda)
    # add the dust internal to the distant galaxy
    tmpgal.addCCMDust(a_gal, b_gal, ebv=ebv_gal[i])
    # redshift the galaxy
    tmpgal.redshiftSED(redshifts[i], dimming=False)
    # add the dust from our milky way - have to recalculate a/b because now wavelenghts
    # for each galaxy are *different*
    a_mw, b_mw = tmpgal.setupCCMab()
    tmpgal.addCCMDust(a_mw, b_mw, ebv=ebv_mw[i])
    tmpgal.multiplyFluxNorm(fluxnorm[i])
    mags[i] = tmpgal.calcMag(rband)


# show results
print "#sedname      fluxnorm     redshift  ebv_gal   ebv_mw  magnitude "
for i in range(len(galaxykeys)):
    print "%s %.5g  %.3f %.5f %.5f %.5f" %(galaxykeys[i], fluxnorm[i], redshifts[i], ebv_gal[i], ebv_mw[i], mags[i])
    
예제 #47
0
            
            if wavelen[0]>9.0:
                coeffs = numpy.polyfit(numpy.log10(wavelen[:100]), numpy.log10(flux[:100]), deg=1)
                redWavelen = numpy.arange(9.0, wavelen[0]-0.5, 0.4*(wavelen[0]-0.5-9.0))
                redFlux = numpy.ones(len(redWavelen))*10e-5
                wavelen = numpy.append(redWavelen, wavelen)
                flux = numpy.append(redFlux, flux)

            with gzip.open(outName,'wb') as spectralFile:
                for w,f in zip(wavelen, flux):
                    spectralFile.write('%e %e\n' % (w,f))


            dummySed = Sed(wavelen=wavelen, flambda=flux)
            sdssMags = sdssPhotometry.manyMagCalc_list(dummySed)
            dummySed = Sed(wavelen=wavelen, flambda=flux)
            magNorm = dummySed.calcMag(controlBandpass)
            output.write('%s is %s -- norm %e -- %e %e %e %e %e %e\n' % 
                        (name, _fitNames[dex], norm,
                         sdssMags[0], sdssMags[1], sdssMags[2], sdssMags[3], sdssMags[4],
                         magNorm))

            if 'BD1000' in outName:
                outName = outName.replace('BD1000','BD1000e')
                for wavelenStr in linesDict:
                    dex = numpy.argmin(numpy.abs(wavelen-0.1*numpy.float(wavelenStr)))
                    flux[dex] = linesDict[wavelenStr]
                with gzip.open(outName,'wb') as spectralFile:
                    for w, f in zip(wavelen, flux):
                        spectralFile.write('%e %e\n' % (w,f))
예제 #48
0
class TwilightInterp(object):

    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 printFitsUsed(self):
        """
        Print out the fit parameters being used
        """
        print('\\tablehead{\colhead{Filter} & \colhead{$r_{12/z}$} & \colhead{$a$ (1/radians)} & \colhead{$b$ (1/airmass)} & \colhead{$c$ (az term/airmass)} & \colhead{$f_z_dark$ (erg/s/cm$^2$)$\\times 10^8$} & \colhead{m$_z_dark$}}')
        for key in self.fitResults:
            numbers = ''
            for num in self.fitResults[key]:
                if num > .001:
                    numbers += ' & %.2f' % num
                else:
                    numbers += ' & %.2f' % (num*1e8)
            print(key, numbers, ' & ', '%.2f' % (-2.5*np.log10(self.fitResults[key][-1])+np.log10(3631.)))

    def __call__(self, intepPoints, filterNames=['u', 'g', 'r', 'i', 'z', 'y']):
        if self.mags:
            return self.interpMag(intepPoints, filterNames=filterNames)
        else:
            return self.interpSpec(intepPoints)

    def interpMag(self, interpPoints, maxAM=2.5,
                  limits=[np.radians(-5.), np.radians(-20.)],
                  filterNames=['u', 'g', 'r', 'i', 'z', 'y']):
        """
        Originally fit the twilight with a cutoff of sun altitude of -11 degrees. I think it can be safely
        extrapolated farther, but be warned you may be entering a regime where it breaks down.
        """
        npts = len(filterNames)
        result = np.zeros((np.size(interpPoints), npts), dtype=float)

        good = np.where((interpPoints['sunAlt'] >= np.min(limits)) &
                        (interpPoints['sunAlt'] <= np.max(limits)) &
                        (interpPoints['airmass'] <= maxAM) &
                        (interpPoints['airmass'] >= 1.))[0]

        for i, filterName in enumerate(filterNames):
            result[good, i] = twilightFunc(interpPoints[good],
                                           *self.lsstEquations[self.filterNameDict[filterName], :].tolist())

        return {'spec': result, 'wave': self.lsstEffWave}

    def interpSpec(self, interpPoints, maxAM=2.5,
                   limits=[np.radians(-5.), np.radians(-20.)]):
        """
        interpPoints should have airmass, azRelSun, and sunAlt.
        """

        npts = np.size(self.solarWave)
        result = np.zeros((np.size(interpPoints), npts), dtype=float)

        good = np.where((interpPoints['sunAlt'] >= np.min(limits)) &
                        (interpPoints['sunAlt'] <= np.max(limits)) &
                        (interpPoints['airmass'] <= maxAM) &
                        (interpPoints['airmass'] >= 1.))[0]

        # Compute the expected flux in each of the filters that we have fits for
        fluxes = []
        for filterName in self.filterNames:
            fluxes.append(twilightFunc(interpPoints[good], *self.fitResults[filterName]))
        fluxes = np.array(fluxes)

        # ratio of model flux to raw solar flux:
        yvals = fluxes.T/(10.**(-0.4*(self.solarMag-np.log10(3631.))))

        # Find wavelengths bluer than cutoff
        blueRegion = np.where(self.solarWave < np.min(self.effWave))

        for i, yval in enumerate(yvals):
            interpF = interp1d(self.effWave, yval, bounds_error=False, fill_value=yval[-1])
            ratio = interpF(self.solarWave)
            interpBlue = InterpolatedUnivariateSpline(self.effWave, yval, k=1)
            ratio[blueRegion] = interpBlue(self.solarWave[blueRegion])
            result[good[i]] = self.solarFlux*ratio

        return {'spec': result, 'wave': self.solarWave}
예제 #49
0
filters = {}
for filtername in keys:
    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'])
    filters[filtername] = tempB

filterWave = np.array([filters[f].calcEffWavelen()[0] for f in keys])

for i, spectrum in enumerate(moonSpectra['spectra']):
    tempSed = Sed()
    tempSed.setSED(moonWave, flambda=spectrum)
    for j, filtName in enumerate(keys):
        try:
            moonSpectra['mags'][i][j] = tempSed.calcMag(filters[filtName])
        except:
            pass


nbreak = 5
nrec = np.size(moonSpectra)

for i in np.arange(nbreak):
    np.savez(os.path.join(outDir, 'moonSpectra_'+str(i)+'.npz'), wave=moonWave,
             spec=moonSpectra[i*nrec/nbreak:(i+1)*nrec/nbreak], filterWave=filterWave)


# Skip this stuff, fixed it later

all_lat, all_az = hp.pix2ang(nside, np.arange(hp.nside2npix(nside)))
# calculate colors
temperatures = numpy.arange(3000, 30000, 1000, dtype='float')
for temperature in temperatures:
    # blackbody: B_lambda dl = (2*h*c^2)/(wavelen^5)*(e^(h*c/(wavelen*k*T))-1)^-1 dl
    # blackbody: B_nu dnu = (2*h/c^2)*nu^3 * (e^(h*nu/k*T)-1)^-1 dnu
    # Set up SED object with blackbody spectrum.
    fnu = ((2.0*PLANCK/LIGHTSPEED**2)*(nu**3) /
           (numpy.e**(PLANCK*nu/BOLTZMAN/temperature)-1))
    blackbody = Sed(wavelen, fnu=fnu)
    # wien's law: wavelen_max(m) = 0.0029/T
    #max = 0.0029/temperature/NM2M
    writestring = "%d " %(temperature)
    # Calculate magnitudes.
    sdssmag = {}
    for f in sdssflist:
        sdssmag[f] = blackbody.calcMag(sdss[f])
    lsstmag = {}
    for f in lsstflist:
        lsstmag[f] = blackbody.calcMag(lsst[f])
    # Calculate colors. 
    for i in range(len(sdssflist)-1):
        col = sdssmag[sdssflist[i]] - sdssmag[sdssflist[i+1]]
        writestring = writestring + "%.3f " %(col)
    for i in range(len(lsstflist)-1):
        col = lsstmag[lsstflist[i]] - lsstmag[lsstflist[i+1]]
        writestring = writestring + "%.3f " %(col)    
    print writestring


예제 #51
0
class TwilightInterp(object):
    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 printFitsUsed(self):
        """
        Print out the fit parameters being used
        """
        print(
            '\\tablehead{\colhead{Filter} & \colhead{$r_{12/z}$} & \colhead{$a$ (1/radians)} & \colhead{$b$ (1/airmass)} & \colhead{$c$ (az term/airmass)} & \colhead{$f_z_dark$ (erg/s/cm$^2$)$\\times 10^8$} & \colhead{m$_z_dark$}}'
        )
        for key in self.fitResults:
            numbers = ''
            for num in self.fitResults[key]:
                if num > .001:
                    numbers += ' & %.2f' % num
                else:
                    numbers += ' & %.2f' % (num * 1e8)
            print(
                key, numbers, ' & ', '%.2f' %
                (-2.5 * np.log10(self.fitResults[key][-1]) + np.log10(3631.)))

    def __call__(self,
                 intepPoints,
                 filterNames=['u', 'g', 'r', 'i', 'z', 'y']):
        if self.mags:
            return self.interpMag(intepPoints, filterNames=filterNames)
        else:
            return self.interpSpec(intepPoints)

    def interpMag(self,
                  interpPoints,
                  maxAM=2.5,
                  limits=[np.radians(-5.), np.radians(-20.)],
                  filterNames=['u', 'g', 'r', 'i', 'z', 'y']):
        """
        Originally fit the twilight with a cutoff of sun altitude of -11 degrees. I think it can be safely
        extrapolated farther, but be warned you may be entering a regime where it breaks down.
        """
        npts = len(filterNames)
        result = np.zeros((np.size(interpPoints), npts), dtype=float)

        good = np.where((interpPoints['sunAlt'] >= np.min(limits))
                        & (interpPoints['sunAlt'] <= np.max(limits))
                        & (interpPoints['airmass'] <= maxAM)
                        & (interpPoints['airmass'] >= 1.))[0]

        for i, filterName in enumerate(filterNames):
            result[good, i] = twilightFunc(
                interpPoints[good], *self.lsstEquations[
                    self.filterNameDict[filterName], :].tolist())

        return {'spec': result, 'wave': self.lsstEffWave}

    def interpSpec(self,
                   interpPoints,
                   maxAM=2.5,
                   limits=[np.radians(-5.), np.radians(-20.)]):
        """
        interpPoints should have airmass, azRelSun, and sunAlt.
        """

        npts = np.size(self.solarWave)
        result = np.zeros((np.size(interpPoints), npts), dtype=float)

        good = np.where((interpPoints['sunAlt'] >= np.min(limits))
                        & (interpPoints['sunAlt'] <= np.max(limits))
                        & (interpPoints['airmass'] <= maxAM)
                        & (interpPoints['airmass'] >= 1.))[0]

        # Compute the expected flux in each of the filters that we have fits for
        fluxes = []
        for filterName in self.filterNames:
            fluxes.append(
                twilightFunc(interpPoints[good], *self.fitResults[filterName]))
        fluxes = np.array(fluxes)

        # ratio of model flux to raw solar flux:
        yvals = fluxes.T / (10.**(-0.4 * (self.solarMag - np.log10(3631.))))

        # Find wavelengths bluer than cutoff
        blueRegion = np.where(self.solarWave < np.min(self.effWave))

        for i, yval in enumerate(yvals):
            interpF = interp1d(self.effWave,
                               yval,
                               bounds_error=False,
                               fill_value=yval[-1])
            ratio = interpF(self.solarWave)
            interpBlue = InterpolatedUnivariateSpline(self.effWave, yval, k=1)
            ratio[blueRegion] = interpBlue(self.solarWave[blueRegion])
            result[good[i]] = self.solarFlux * ratio

        return {'spec': result, 'wave': self.solarWave}
bpfile = 'exampleBandpass.dat'
rband.readThroughput(bpfile)

# Instantiate a Sed object to hold the spectral energy distribution information
star = Sed()
# Read the Sed data file into that object -
#  (note that exampleSED.dat contains wavelength/F_lambda .. but is possible to also
#    read in wavelength/F_nu data using readSED_fnu)
sedfile = 'exampleSED.dat'
star.readSED_flambda(sedfile)

print ""
print "Read %s into Bandpass and %s into Sed." %(bpfile, sedfile)

# Simply calculate the magnitude of this source in the bandpass.
mag = star.calcMag(rband)

print ""
print "Without any scaling of the SED, the magnitude is %.4f" %(mag)

# That was probably pretty small, right? Maybe we actually know what
# magnitude we expect this source to have in this bandpass, and then want to scale
# the SED to that appropriate magnitude (and then calculate the magnitudes once it's
# scaled properly, in other bandpasses).

mag_desired = 24.5
print "Now going to apply a scaling factor to the SED to set magnitude to %.4f" %(mag_desired)

# Calculate the scaling factor.
fluxnorm = star.calcFluxNorm(mag_desired, rband)
# Apply the scaling factor. 
def packageZodiacal():

    dataDir = getPackageDir('SIMS_SKYBRIGHTNESS_DATA')
    outDir = os.path.join(dataDir, 'ESO_Spectra/Zodiacal')

    nside = 4

    # Read in all the spectra from ESO call and package into a single npz file

    files = glob.glob('Zodiacal/skytable*.fits')

    temp = pyfits.open(files[0])
    wave = temp[1].data['lam'].copy()*1e3

    airmasses = []
    eclLon = []
    eclLat = []
    specs = []

    for i,filename in enumerate(files):
        fits = pyfits.open(filename)
        if np.max(fits[1].data['flux']) > 0:
            specs.append(fits[1].data['flux'].copy())
            header = fits[0].header['comment']
            for card in header:
                if 'SKYMODEL.TARGET.AIRMASS' in card:
                    airmasses.append(float(card.split('=')[-1]))
                elif 'SKYMODEL.ECL.LON' in card:
                    eclLon.append(float(card.split('=')[-1]))
                elif 'SKYMODEL.ECL.LAT' in card:
                    eclLat.append(float(card.split('=')[-1]))


    airmasses = np.array(airmasses)
    eclLon = np.array(eclLon)
    eclLat = np.array(eclLat)

    wrapA = np.where(eclLon < 0.)
    eclLon[wrapA] = eclLon[wrapA]+360.

    uAM = np.unique(airmasses)
    nAM = uAM.size
    nwave = wave.size

    dtype = [('airmass', 'float'),
             ('hpid', 'int' ),
             ('spectra', 'float', (nwave)), ('mags', 'float', (6))]
    npix = hp.nside2npix(nside)
    Spectra = np.zeros(nAM*npix, dtype=dtype)
    for i,am in enumerate(uAM):
        Spectra['airmass'][i*npix:i*npix+npix] = am
        Spectra['hpid'][i*npix:i*npix+npix] = np.arange(npix)


    for am, lat, lon, spec in zip(airmasses,eclLat, eclLon, specs):
        hpid = hp.ang2pix(nside, np.radians(lat+90.), np.radians(lon) )
        good = np.where( (Spectra['airmass'] == am) & (Spectra['hpid'] == hpid))
        Spectra['spectra'][good] = spec.copy()

    hPlank = 6.626068e-27 # erg s
    cLight = 2.99792458e10 # cm/s

    # Convert spectra from ph/s/m2/micron/arcsec2 to erg/s/cm2/nm/arcsec2
    Spectra['spectra'] = Spectra['spectra']/(100.**2)*hPlank*cLight/(wave*1e-7)/1e3

    # Sort things since this might be helpful later
    Spectra.sort(order=['airmass', 'hpid'])

    # Load LSST filters
    throughPath = os.path.join(getPackageDir('throughputs'),'baseline')
    keys = ['u','g','r','i','z','y']
    nfilt = len(keys)
    filters = {}
    for filtername in keys:
        bp = np.loadtxt(os.path.join(throughPath, 'filter_'+filtername+'.dat'),
                        dtype=zip(['wave','trans'],[float]*2 ))
        tempB = Bandpass()
        tempB.setBandpass(bp['wave'],bp['trans'])
        filters[filtername] = tempB

    filterWave = np.array([filters[f].calcEffWavelen()[0] for f in keys ])

    for i,spectrum in enumerate(Spectra['spectra']):
        tempSed = Sed()
        tempSed.setSED(wave,flambda=spectrum)
        for j,filtName in enumerate(keys):
            try:
                Spectra['mags'][i][j] = tempSed.calcMag(filters[filtName])
            except:
                pass


    #span this over multiple files to store in github
    nbreak = 3
    nrec = np.size(Spectra)

    for i in np.arange(nbreak):
        np.savez(os.path.join(outDir,'zodiacalSpectra_'+str(i)+'.npz'), wave = wave,
                 spec=Spectra[i*nrec/nbreak:(i+1)*nrec/nbreak], filterWave=filterWave)
    query += 'galaxy WHERE varParamStr IS NOT NULL '
    query += 'AND dec BETWEEN -2.5 AND 2.5 '
    query += 'AND (ra<2.5 OR ra>357.5)'

    dtype = np.dtype([('magnorm', float), ('redshift', float),
                      ('varParamStr', str, 400)])

    data_iter = db.get_arbitrary_chunk_iterator(query,
                                                dtype=dtype,
                                                chunk_size=10000)

    with open('data/dc1_agn_params.txt', 'w') as out_file:
        out_file.write('# z m_i M_i tau sfu sfg sfr sfi sfz sfy\n')
        for chunk in data_iter:
            DM = cosmo.distanceModulus(redshift=chunk['redshift'])
            k_corr = np.interp(chunk['redshift'], z_grid, k_grid)

            for i_row, agn in enumerate(chunk):
                ss = Sed(wavelen=base_sed.wavelen, flambda=base_sed.flambda)
                fnorm = getImsimFluxNorm(ss, agn['magnorm'])
                ss.multiplyFluxNorm(fnorm)
                ss.redshiftSED(agn['redshift'], dimming=True)
                mag = ss.calcMag(bp)
                abs_m_i = mag - DM[i_row] - k_corr[i_row]
                params = json.loads(agn['varParamStr'])['pars']
                out_file.write(
                    '%e %e %e %e %e %e %e %e %e %e\n' %
                    (agn['redshift'], mag, abs_m_i, params['agn_tau'],
                     params['agn_sfu'], params['agn_sfg'], params['agn_sfr'],
                     params['agn_sfi'], params['agn_sfz'], params['agn_sfy']))
def packageLowerAtm():

    dataDir = getPackageDir('SIMS_SKYBRIGHTNESS_DATA')
    outDir = os.path.join(dataDir, 'ESO_Spectra/LowerAtm')

    # Read in all the spectra from ESO call and package into a single npz file

    files = glob.glob('LowerAtm/skytable*.fits')

    temp = pyfits.open(files[0])
    wave = temp[1].data['lam'].copy()*1e3

    airmasses = []
    nightTimes = []
    specs = []

    for i,filename in enumerate(files):
        fits = pyfits.open(filename)
        if np.max(fits[1].data['flux']) > 0:
            specs.append(fits[1].data['flux'].copy())
            header = fits[0].header['comment']
            for card in header:
                if 'SKYMODEL.TARGET.AIRMASS' in card:
                    airmasses.append(float(card.split('=')[-1]))
                elif 'SKYMODEL.TIME' in card:
                    nightTimes.append(float(card.split('=')[-1]))

    airmasses = np.array(airmasses)
    nigtTimes = np.array(nightTimes)

    nrec = airmasses.size
    nwave = wave.size

    dtype = [('airmass', 'float'),
             ('nightTimes', 'float'),
             ('spectra', 'float', (nwave)), ('mags', 'float', (6))]
    Spectra = np.zeros(nrec, dtype=dtype)
    Spectra['airmass'] = airmasses
    Spectra['nightTimes'] = nightTimes
    Spectra['spectra'] = specs

    hPlank = 6.626068e-27 # erg s
    cLight = 2.99792458e10 # cm/s

    # Convert spectra from ph/s/m2/micron/arcsec2 to erg/s/cm2/nm/arcsec2
    Spectra['spectra'] = Spectra['spectra']/(100.**2)*hPlank*cLight/(wave*1e-7)/1e3

    # Sort things since this might be helpful later
    Spectra.sort(order=['airmass','nightTimes'])

    # Load LSST filters
    throughPath = os.path.join(getPackageDir('throughputs'),'baseline')
    keys = ['u','g','r','i','z','y']
    nfilt = len(keys)
    filters = {}
    for filtername in keys:
        bp = np.loadtxt(os.path.join(throughPath, 'filter_'+filtername+'.dat'),
                        dtype=zip(['wave','trans'],[float]*2 ))
        tempB = Bandpass()
        tempB.setBandpass(bp['wave'],bp['trans'])
        filters[filtername] = tempB

    filterWave = np.array([filters[f].calcEffWavelen()[0] for f in keys ])

    for i,spectrum in enumerate(Spectra['spectra']):
        tempSed = Sed()
        tempSed.setSED(wave,flambda=spectrum)
        for j,filtName in enumerate(keys):
            try:
                Spectra['mags'][i][j] = tempSed.calcMag(filters[filtName])
            except:
                pass

    np.savez(os.path.join(outDir,'Spectra.npz'), wave = wave, spec=Spectra, filterWave=filterWave)
예제 #56
0
seds.remove('harris_V.dat')

print 'Calculating colors for seds: \n', seds

writestring = 'Sed '
for f in filterlist:
    writestring += 'V-%s ' %(f)
print writestring


fig = plt.figure()
for s in seds:
    sed = Sed()
    sed.readSED_flambda(s)
    sname = s.replace('.dat', '')
    vmag = sed.calcMag(harrisV)
    colors = {}
    writestring = '%s ' %(sname)
    for f in filterlist:
        mag = sed.calcMag(lsst[f])
        colors[f] = vmag - mag
        writestring += '%.3f ' %(colors[f])
    print writestring
    plotPointColor = np.random.rand(3)
    plt.plot(colors['g'], colors['r'], linestyle='', marker='o', color=plotPointColor, label='%s' %(sname))
    pylab.annotate(sname, colors['g']+0.005, colors['r']+0.005, color=plotPointColor)

plt.xlabel('V-g')
plt.ylabel('V-r')
#plt.legend(fancybox=True, numpoints=1, fontsize='smaller')
plt.show()
def calcM5(hardware, system, atmos, title='m5'):
    """
    Calculate m5 values for all filters in hardware and system.
    Prints all values that go into "table 2" of the overview paper.
    Returns dictionary of m5 values.
    """
    # photParams stores default values for the exposure time, nexp, size of the primary,
    #  readnoise, gain, platescale, etc.
    # See https://github.com/lsst/sims_photUtils/blob/master/python/lsst/sims/photUtils/PhotometricParameters.py
    photParams = PhotometricParameters(gain=1)
    photParams_infinity = PhotometricParameters(readnoise=0, darkcurrent=0,
                                                othernoise=0, gain=1)
    # lsstDefaults stores default values for the FWHMeff.
    # See https://github.com/lsst/sims_photUtils/blob/master/python/lsst/sims/photUtils/LSSTdefaults.py
    lsstDefaults = LSSTdefaults()
    darksky = Sed()
    darksky.readSED_flambda(os.path.join('../siteProperties', 'darksky.dat'))
    flatSed = Sed()
    flatSed.setFlatSED()
    m5 = {}
    Tb = {}
    Sb = {}
    kAtm = {}
    Cm = {}
    dCm_infinity = {}
    sourceCounts = {}
    skyCounts = {}
    skyMag = {}
    gamma = {}
    for f in system:
        m5[f] = SignalToNoise.calcM5(darksky, system[f], hardware[f], photParams,
                                     FWHMeff=lsstDefaults.FWHMeff(f))
        fNorm = flatSed.calcFluxNorm(m5[f], system[f])
        flatSed.multiplyFluxNorm(fNorm)
        sourceCounts[f] = flatSed.calcADU(system[f], photParams=photParams)
        # Calculate the Skycounts expected in this bandpass.
        skyCounts[f] = (darksky.calcADU(hardware[f], photParams=photParams)
                        * photParams.platescale**2)
        # Calculate the sky surface brightness.
        skyMag[f] = darksky.calcMag(hardware[f])
        # Calculate the gamma value.
        gamma[f] = SignalToNoise.calcGamma(system[f], m5[f], photParams)
        # Calculate the "Throughput Integral" (this is the hardware + atmosphere)
        dwavelen = np.mean(np.diff(system[f].wavelen))
        Tb[f] = np.sum(system[f].sb / system[f].wavelen) * dwavelen
        # Calculate the "Sigma" 'system integral' (this is the hardware only)
        Sb[f] = np.sum(hardware[f].sb / hardware[f].wavelen) * dwavelen
        # Calculate km - atmospheric extinction in a particular bandpass
        kAtm[f] = -2.5*np.log10(Tb[f] / Sb[f])
        # Calculate the Cm and Cm_Infinity values.
        # m5 = Cm + 0.5*(msky - 21) + 2.5log10(0.7/FWHMeff) + 1.25log10(t/30) - km(X-1.0)
        # Exptime should be 30 seconds and X=1.0
        exptime = photParams.exptime * photParams.nexp
        if exptime != 30.0:
            print "Whoa, exposure time was not as expected - got %s not 30 seconds. Please edit Cm calculation." %(exptime)
        # Assumes atmosphere used in system throughput is X=1.0
        X = 1.0
        Cm[f] = (m5[f] - 0.5*(skyMag[f] - 21) - 2.5*np.log10(0.7/lsstDefaults.FWHMeff(f)))
        # Calculate Cm_Infinity by setting readout noise to zero.
        m5inf = SignalToNoise.calcM5(darksky, system[f], hardware[f],  photParams_infinity,
                                     FWHMeff=lsstDefaults.FWHMeff(f))
        Cm_infinity = (m5inf - 0.5*(skyMag[f] - 21)
                       - 2.5*np.log10(0.7/lsstDefaults.FWHMeff(f)))
        dCm_infinity[f] = Cm_infinity - Cm[f]
    print title
    print 'Filter FWHMeff FWHMgeom SkyMag SkyCounts Tb Sb kAtm Gamma Cm dCm_infinity m5 SourceCounts'
    for f in ('u', 'g' ,'r', 'i', 'z', 'y'):
        print '%s %.2f %.2f %.2f %.1f %.3f %.3f %.4f %.6f %.2f %.2f %.2f %.2f'\
           %(f, lsstDefaults.FWHMeff(f),
             SignalToNoise.FWHMeff2FWHMgeom(lsstDefaults.FWHMeff(f)),
             skyMag[f], skyCounts[f], Tb[f], Sb[f], kAtm[f],
             gamma[f], Cm[f], dCm_infinity[f], m5[f], sourceCounts[f])

    # Show what these look like individually (add sky & m5 limits on throughput curves)
    plt.figure()
    for f in filterlist:
        plt.plot(system[f].wavelen, system[f].sb, color=filtercolors[f], linewidth=2, label=f)
    plt.plot(atmosphere.wavelen, atmosphere.sb, 'k:', label='X=1.0')
    plt.legend(loc='center right', fontsize='smaller')
    plt.xlim(300, 1100)
    plt.ylim(0, 1)
    plt.xlabel('Wavelength (nm)')
    plt.ylabel('Throughput')
    plt.title('System Throughputs')
    plt.grid(True)

    plt.figure()
    ax = plt.gca()
    # Add dark sky
    ax2 = ax.twinx()
    plt.sca(ax2)
    skyab = -2.5*np.log10(darksky.fnu) - darksky.zp
    ax2.plot(darksky.wavelen, skyab,
             'k-', linewidth=0.8, label='Dark sky mags')
    ax2.set_ylabel('AB mags')
    ax2.set_ylim(24, 14)
    plt.sca(ax)
    # end of dark sky
    handles = []
    for f in filterlist:
        plt.plot(system[f].wavelen, system[f].sb, color=filtercolors[f], linewidth=2)
        myline = mlines.Line2D([], [], color=filtercolors[f], linestyle='-', linewidth=2,
                               label = '%s: m5 %.1f (sky %.1f)' %(f, m5[f], skyMag[f]))
        handles.append(myline)
    plt.plot(atmos.wavelen, atmos.sb, 'k:', label='Atmosphere, X=1.0')
    # Add legend for dark sky.
    myline = mlines.Line2D([], [], color='k', linestyle='-', label='Dark sky AB mags/arcsec^2')
    handles.append(myline)
    # end of dark sky legend line
    plt.legend(loc=(0.01, 0.69), handles=handles, fancybox=True, numpoints=1, fontsize='small')
    plt.ylim(0, 1)
    plt.xlim(300, 1100)
    plt.xlabel('Wavelength (nm)')
    plt.ylabel('Fractional Throughput Response')
    plt.title('System total response curves %s' %(title))
    return m5
예제 #58
0
class TestSNRmethods(unittest.TestCase):

    def setUp(self):

        starName = os.path.join(lsst.utils.getPackageDir('sims_photUtils'),
                                'tests/cartoonSedTestData/starSed/')
        starName = os.path.join(starName, 'kurucz', 'km20_5750.fits_g40_5790.gz')
        self.starSED = Sed()
        self.starSED.readSED_flambda(starName)
        imsimband = Bandpass()
        imsimband.imsimBandpass()
        fNorm = self.starSED.calcFluxNorm(22.0, imsimband)
        self.starSED.multiplyFluxNorm(fNorm)

        hardwareDir = os.path.join(lsst.utils.getPackageDir('throughputs'), 'baseline')
        componentList = ['detector.dat', 'm1.dat', 'm2.dat', 'm3.dat',
                         'lens1.dat', 'lens2.dat', 'lens3.dat']
        self.skySed = Sed()
        self.skySed.readSED_flambda(os.path.join(hardwareDir, 'darksky.dat'))

        totalNameList = ['total_u.dat', 'total_g.dat', 'total_r.dat', 'total_i.dat',
                         'total_z.dat', 'total_y.dat']

        self.bpList = []
        self.hardwareList = []
        for name in totalNameList:
            dummy = Bandpass()
            dummy.readThroughput(os.path.join(hardwareDir, name))
            self.bpList.append(dummy)

            dummy = Bandpass()
            hardwareNameList = [os.path.join(hardwareDir, name)]
            for component in componentList:
                hardwareNameList.append(os.path.join(hardwareDir, component))
            dummy.readThroughputList(hardwareNameList)
            self.hardwareList.append(dummy)

        self.filterNameList = ['u', 'g', 'r', 'i', 'z', 'y']

    def testMagError(self):
        """
        Make sure that calcMagError_sed and calcMagError_m5
        agree to within 0.001
        """
        defaults = LSSTdefaults()
        photParams = PhotometricParameters()

        # create a cartoon spectrum to test on
        spectrum = Sed()
        spectrum.setFlatSED()
        spectrum.multiplyFluxNorm(1.0e-9)

        # find the magnitudes of that spectrum in our bandpasses
        magList = []
        for total in self.bpList:
            magList.append(spectrum.calcMag(total))
        magList = np.array(magList)

        # try for different normalizations of the skySED
        for fNorm in np.arange(1.0, 5.0, 1.0):
            self.skySed.multiplyFluxNorm(fNorm)

            for total, hardware, filterName, mm in \
                zip(self.bpList, self.hardwareList, self.filterNameList, magList):

                FWHMeff = defaults.FWHMeff(filterName)

                m5 = snr.calcM5(self.skySed, total, hardware, photParams, FWHMeff=FWHMeff)

                sigma_sed = snr.calcMagError_sed(spectrum, total, self.skySed,
                                                 hardware, photParams, FWHMeff=FWHMeff)

                sigma_m5, gamma = snr.calcMagError_m5(mm, total, m5, photParams)

                self.assertAlmostEqual(sigma_m5, sigma_sed, 3)

    def testVerboseSNR(self):
        """
        Make sure that calcSNR_sed has everything it needs to run in verbose mode
        """
        photParams = PhotometricParameters()

        # create a cartoon spectrum to test on
        spectrum = Sed()
        spectrum.setFlatSED()
        spectrum.multiplyFluxNorm(1.0e-9)

        snr.calcSNR_sed(spectrum, self.bpList[0], self.skySed,
                        self.hardwareList[0], photParams, FWHMeff=0.7, verbose=True)

    def testSignalToNoise(self):
        """
        Test that calcSNR_m5 and calcSNR_sed give similar results
        """
        defaults = LSSTdefaults()
        photParams = PhotometricParameters()

        m5 = []
        for i in range(len(self.hardwareList)):
            m5.append(snr.calcM5(self.skySed, self.bpList[i],
                      self.hardwareList[i],
                      photParams, FWHMeff=defaults.FWHMeff(self.filterNameList[i])))

        sedDir = os.path.join(lsst.utils.getPackageDir('sims_photUtils'),
                              'tests/cartoonSedTestData/starSed/')
        sedDir = os.path.join(sedDir, 'kurucz')
        fileNameList = os.listdir(sedDir)

        rng = np.random.RandomState(42)
        offset = rng.random_sample(len(fileNameList))*2.0

        for ix, name in enumerate(fileNameList):
            if ix > 100:
                break
            spectrum = Sed()
            spectrum.readSED_flambda(os.path.join(sedDir, name))
            ff = spectrum.calcFluxNorm(m5[2]-offset[ix], self.bpList[2])
            spectrum.multiplyFluxNorm(ff)
            for i in range(len(self.bpList)):
                control_snr = snr.calcSNR_sed(spectrum, self.bpList[i],
                                              self.skySed,
                                              self.hardwareList[i],
                                              photParams, defaults.FWHMeff(self.filterNameList[i]))

                mag = spectrum.calcMag(self.bpList[i])

                test_snr, gamma = snr.calcSNR_m5(mag, self.bpList[i], m5[i], photParams)
                self.assertLess((test_snr-control_snr)/control_snr, 0.001)

    def testSystematicUncertainty(self):
        """
        Test that systematic uncertainty is added correctly.
        """
        sigmaSys = 0.002
        m5_list = [23.5, 24.3, 22.1, 20.0, 19.5, 21.7]
        photParams = PhotometricParameters(sigmaSys=sigmaSys)

        obs_metadata = ObservationMetaData(pointingRA=23.0, pointingDec=45.0,
                                           m5=m5_list, bandpassName=self.filterNameList)
        magnitude_list = []
        for bp in self.bpList:
            mag = self.starSED.calcMag(bp)
            magnitude_list.append(mag)

        for bp, hardware, filterName, mm, m5 in \
            zip(self.bpList, self.hardwareList, self.filterNameList, magnitude_list, m5_list):

            skyDummy = Sed()
            skyDummy.readSED_flambda(os.path.join(lsst.utils.getPackageDir('throughputs'),
                                     'baseline', 'darksky.dat'))

            normalizedSkyDummy = setM5(obs_metadata.m5[filterName], skyDummy,
                                       bp, hardware,
                                       FWHMeff=LSSTdefaults().FWHMeff(filterName),
                                       photParams=photParams)

            sigma, gamma = snr.calcMagError_m5(mm, bp, m5, photParams)

            snrat = snr.calcSNR_sed(self.starSED, bp, normalizedSkyDummy, hardware,
                                    FWHMeff=LSSTdefaults().FWHMeff(filterName),
                                    photParams=PhotometricParameters())

            testSNR, gamma = snr.calcSNR_m5(mm, bp, m5, photParams=PhotometricParameters(sigmaSys=0.0))

            self.assertAlmostEqual(snrat, testSNR, 10,
                                   msg = 'failed on calcSNR_m5 test %e != %e '
                                   % (snrat, testSNR))

            control = np.sqrt(np.power(snr.magErrorFromSNR(testSNR), 2) + np.power(sigmaSys, 2))

            msg = '%e is not %e; failed' % (sigma, control)

            self.assertAlmostEqual(sigma, control, 10, msg=msg)

    def testNoSystematicUncertainty(self):
        """
        Test that systematic uncertainty is handled correctly when set to None.
        """
        m5_list = [23.5, 24.3, 22.1, 20.0, 19.5, 21.7]
        photParams = PhotometricParameters(sigmaSys=0.0)

        obs_metadata = ObservationMetaData(pointingRA=23.0, pointingDec=45.0,
                                           m5=m5_list, bandpassName=self.filterNameList)

        magnitude_list = []
        for bp in self.bpList:
            mag = self.starSED.calcMag(bp)
            magnitude_list.append(mag)

        for bp, hardware, filterName, mm, m5 in \
            zip(self.bpList, self.hardwareList, self.filterNameList, magnitude_list, m5_list):

            skyDummy = Sed()
            skyDummy.readSED_flambda(os.path.join(lsst.utils.getPackageDir('throughputs'),
                                     'baseline', 'darksky.dat'))

            normalizedSkyDummy = setM5(obs_metadata.m5[filterName], skyDummy,
                                       bp, hardware,
                                       FWHMeff=LSSTdefaults().FWHMeff(filterName),
                                       photParams=photParams)

            sigma, gamma = snr.calcMagError_m5(mm, bp, m5, photParams)

            snrat = snr.calcSNR_sed(self.starSED, bp, normalizedSkyDummy, hardware,
                                    FWHMeff=LSSTdefaults().FWHMeff(filterName),
                                    photParams=PhotometricParameters())

            testSNR, gamma = snr.calcSNR_m5(mm, bp, m5, photParams=PhotometricParameters(sigmaSys=0.0))

            self.assertAlmostEqual(snrat, testSNR, 10,
                                   msg = 'failed on calcSNR_m5 test %e != %e '
                                   % (snrat, testSNR))

            control = snr.magErrorFromSNR(testSNR)

            msg = '%e is not %e; failed' % (sigma, control)

            self.assertAlmostEqual(sigma, control, 10, msg=msg)

    def testFWHMconversions(self):
        FWHMeff = 0.8
        FWHMgeom = snr.FWHMeff2FWHMgeom(FWHMeff)
        self.assertEqual(FWHMgeom, (0.822*FWHMeff+0.052))
        FWHMgeom = 0.8
        FWHMeff = snr.FWHMgeom2FWHMeff(FWHMgeom)
        self.assertEqual(FWHMeff, (FWHMgeom-0.052)/0.822)

    def testSNR_arr(self):
        """
        Test that calcSNR_m5 works on numpy arrays of magnitudes
        """
        rng = np.random.RandomState(17)
        mag_list = rng.random_sample(100)*5.0 + 15.0

        photParams = PhotometricParameters()
        bp = self.bpList[0]
        m5 = 24.0
        control_list = []
        for mm in mag_list:
            ratio, gamma = snr.calcSNR_m5(mm, bp, m5, photParams)
            control_list.append(ratio)
        control_list = np.array(control_list)

        test_list, gamma = snr.calcSNR_m5(mag_list, bp, m5, photParams)

        np.testing.assert_array_equal(control_list, test_list)

    def testError_arr(self):
        """
        Test that calcMagError_m5 works on numpy arrays of magnitudes
        """
        rng = np.random.RandomState(17)
        mag_list = rng.random_sample(100)*5.0 + 15.0

        photParams = PhotometricParameters()
        bp = self.bpList[0]
        m5 = 24.0
        control_list = []
        for mm in mag_list:
            sig, gamma = snr.calcMagError_m5(mm, bp, m5, photParams)
            control_list.append(sig)
        control_list = np.array(control_list)

        test_list, gamma = snr.calcMagError_m5(mag_list, bp, m5, photParams)

        np.testing.assert_array_equal(control_list, test_list)