Пример #1
0
    def Calc_m5(self, filtre):

        filtre_trans = self.system[filtre]
        wavelen_min, wavelen_max, wavelen_step = filtre_trans.getWavelenLimits(
            None, None, None)

        bandpass = Bandpass(wavelen=filtre_trans.wavelen, sb=filtre_trans.sb)

        flatSedb = Sed()
        flatSedb.setFlatSED(wavelen_min, wavelen_max, wavelen_step)
        flux0b = np.power(10., -0.4 * self.mag_sky[filtre])
        flatSedb.multiplyFluxNorm(flux0b)
        photParams = PhotometricParameters(bandpass=filtre)
        norm = photParams.platescale**2 / 2. * photParams.exptime / photParams.gain
        if self.atmos:
            self.data['m5'][filtre] = SignalToNoise.calcM5(
                flatSedb,
                self.atmosphere[filtre],
                self.system[filtre],
                photParams=photParams,
                FWHMeff=self.FWHMeff[filtre])
            adu_int = flatSedb.calcADU(bandpass=self.atmosphere[filtre],
                                       photParams=photParams)
            self.data['flux_sky'][filtre] = adu_int * norm
        else:
            self.data['m5'][filtre] = SignalToNoise.calcM5(
                flatSedb,
                self.system[filtre],
                self.system[filtre],
                photParams=photParams,
                FWHMeff=self.FWHMeff[filtre])
            adu_int = flatSedb.calcADU(bandpass=self.system[filtre],
                                       photParams=photParams)
            self.data['flux_sky'][filtre] = adu_int * norm
Пример #2
0
    def ZP_filtre(self, filtre):

        self.data['Skyb'][filtre] = self.Cte * np.power(
            self.Diameter / 6.5,
            2.) * np.power(self.DeltaT / 30., 2.) * np.power(
                self.platescale, 2.) * np.power(
                    10., 0.4 *
                    (25. - self.mag_sky[filtre])) * self.Sigmab[filtre]

        Zb = 181.8 * np.power(self.Diameter / 6.5, 2.) * self.Tb[filtre]
        mbZ = 25. + 2.5 * np.log10(Zb)
        filtre_trans = self.throughputs.system[filtre]
        wavelen_min, wavelen_max, wavelen_step = filtre_trans.getWavelenLimits(
            None, None, None)
        bandpass = Bandpass(wavelen=filtre_trans.wavelen, sb=filtre_trans.sb)
        flatSed = Sed()
        flatSed.setFlatSED(wavelen_min, wavelen_max, wavelen_step)
        flux0 = np.power(10., -0.4 * mbZ)
        flatSed.multiplyFluxNorm(flux0)
        counts = flatSed.calcADU(
            bandpass,
            photParams=self.photParams)  #number of counts for exptime
        self.data['zp'][filtre] = mbZ
        #print 'hello',counts/self.photParams.exptime
        self.data['counts_zp'][filtre] = counts / self.photParams.exptime
Пример #3
0
    def __call__(self, filter_name='u', magNorm=None):
        """
        This method calls the SkyCountsPerSec object and calculates the sky
        counts.

        @param [in] filter_name is a string that indicates the name of the filter
        for which to make the calculation.

        @param [in] magNorm is an option to calculate the sky counts for a given
        magnitude.  When calculating the counts from just the information in skyModel
        this should be set as MagNorm=None.
        """

        bandpass = self.bandpassdic[filter_name]
        wave, spec = self.skyModel.returnWaveSpec()
        skymodel_Sed = Sed(wavelen=wave, flambda=spec[0, :])
        if magNorm:
            skymodel_fluxNorm = skymodel_Sed.calcFluxNorm(magNorm, bandpass)
            skymodel_Sed.multiplyFluxNorm(skymodel_fluxNorm)
        sky_counts = skymodel_Sed.calcADU(bandpass=bandpass,
                                          photParams=self.photParams)
        expTime = self.photParams.nexp * self.photParams.exptime * u.s
        sky_counts_persec = sky_counts * 0.2**2 / expTime

        return sky_counts_persec
Пример #4
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 _fluxes(sed_name, mag_norm, redshift):
    """
    Find the fluxes for a galaxy component

    Parameters
    ----------
    sed_name is an SED file name

    mag_norm is a float

    redshift is a float

    Returns
    -------
    array of fluxes in ugrizy order
    """
    if not hasattr(_fluxes, '_bp_dict'):
        bp_dir = getPackageDir('throughputs')
        bp_dir = os.path.join(bp_dir, 'imsim', 'goal')
        _fluxes._bp_dict = BandpassDict.loadTotalBandpassesFromFiles(
            bandpassDir=bp_dir)

        _fluxes._sed_dir = getPackageDir('sims_sed_library')

    spec = Sed()
    full_sed_name = os.path.join(_fluxes._sed_dir, sed_name)
    if not os.path.isfile(full_sed_name):
        full_sed_name = os.path.join(_fluxes._sed_dir,
                                     defaultSpecMap[sed_name])
    spec.readSED_flambda(full_sed_name)
    fnorm = getImsimFluxNorm(spec, mag_norm)
    spec.multiplyFluxNorm(fnorm)
    spec.redshiftSED(redshift, dimming=True)
    return _fluxes._bp_dict.fluxListForSed(spec)
    def testStellarPhotometricUncertainties(self):
        """
        Test in the case of a catalog of stars
        """
        lsstDefaults = LSSTdefaults()
        starDB = testStarsDBObj(driver=self.driver, host=self.host, database=self.dbName)
        starCat = testStarCatalog(starDB, obs_metadata=self.obs_metadata)
        phot = PhotometryStars()

        ct = 0
        for line in starCat.iter_catalog():
            starSed = Sed()
            starSed.readSED_flambda(os.path.join(lsst.utils.getPackageDir('sims_sed_library'),
                                                 defaultSpecMap[line[14]]))
            imsimband = Bandpass()
            imsimband.imsimBandpass()
            fNorm = starSed.calcFluxNorm(line[15], imsimband)
            starSed.multiplyFluxNorm(fNorm)

            aV = numpy.float(line[16])
            a_int, b_int = starSed.setupCCMab()
            starSed.addCCMDust(a_int, b_int, A_v=aV)

            for i in range(len(self.bandpasses)):
                controlSigma = calcMagError_sed(starSed, self.totalBandpasses[i],
                                             self.skySeds[i],
                                             self.hardwareBandpasses[i],
                                             FWHMeff=lsstDefaults.FWHMeff(self.bandpasses[i]),
                                             photParams=PhotometricParameters())

                testSigma = line[8+i]
                self.assertAlmostEqual(controlSigma, testSigma, 4)
                ct += 1
        self.assertGreater(ct, 0)
Пример #7
0
def sky_counts_per_sec(skyModel, photParams, bandpass, magNorm=None):
    """
    Compute the sky background counts per pixel per second.  Note that
    the gain in photParams is applied to the return value such that
    "counts" are in units of ADU.

    Parameters
    ----------
    skyModel: lsst.sims.skybrightness.SkyModel
        Model of the sky for the current epoch.
    photParams: lsst.sims.photUtils.PhotometricParameters
        Object containing parameters of the photometric response of the
        telescope, including pixel scale, gain, effective area, exposure
        time, number of exposures, etc.
    bandpass: lsst.sims.photUtils.Bandpass
        Instrumental throughput for a particular passband.
    magNorm: float [None]
        If not None, then renormalize the sky SED to have a monochromatic
        magnitude of magNorm at 500nm.  Otherwise, use the default
        skyModel normalization.

    Returns
    -------
    ADUs per second per pixel
    """
    wave, spec = skyModel.returnWaveSpec()
    sed = Sed(wavelen=wave, flambda=spec[0, :])
    if magNorm is not None:
        flux_norm = sed.calcFluxNorm(magNorm, bandpass)
        sed.multiplyFluxNorm(flux_norm)
    countrate_per_arcsec = sed.calcADU(bandpass=bandpass,
                                       photParams=photParams)
    exptime = photParams.nexp * photParams.exptime
    return countrate_per_arcsec * photParams.platescale**2 / exptime
Пример #8
0
def calculate_mags(sed_name, mag_norm, out_dict):
    """
    Parameters
    ----------
    sed_name is a numpy array of SED names

    mag_norm is a numpy array of magNorms

    out_dict is a multiprocessing.Manager.dict() that will
    store the magnitudes calculated by this process.
    """
    i_process = mp.current_process().pid

    bp_dir = getPackageDir('throughputs')
    bp_dir = os.path.join(bp_dir, 'imsim', 'goal')
    bp_dict =  BandpassDict.loadTotalBandpassesFromFiles(bandpassDir=bp_dir)

    sed_dir = getPackageDir('sims_sed_library')

    out_mags = np.zeros((len(sed_name), 6), dtype=float)
    for i_star, (s_name, m_norm) in enumerate(zip(sed_name, mag_norm)):
        spec = Sed()
        spec.readSED_flambda(os.path.join(sed_dir, defaultSpecMap[s_name]))
        fnorm = getImsimFluxNorm(spec, m_norm)
        spec.multiplyFluxNorm(fnorm)
        mags = bp_dict.magListForSed(spec)
        out_mags[i_star] = mags

    out_dict[i_process] = out_mags
Пример #9
0
    def ZP_filtre(self, filtre):

        photParams = PhotometricParameters(bandpass=filtre)
        Diameter = 2. * np.sqrt(
            photParams.effarea * 1.e-4 / np.pi)  # diameter in meter
        Cte = 3631. * np.pi * Diameter**2 * 2. * photParams.exptime / 4 / h / 1.e36
        #print('hello Cte',Cte,Diameter,h,photParams.exptime)

        self.data['Skyb'][filtre] = Cte * np.power(
            Diameter / 6.5, 2.) * np.power(
                2. * photParams.exptime / 30., 2.) * np.power(
                    photParams.platescale, 2.) * np.power(
                        10., 0.4 *
                        (25. - self.mag_sky[filtre])) * self.Sigmab[filtre]

        Zb = 181.8 * np.power(Diameter / 6.5, 2.) * self.Tb[filtre]
        mbZ = 25. + 2.5 * np.log10(Zb)
        filtre_trans = self.system[filtre]
        wavelen_min, wavelen_max, wavelen_step = filtre_trans.getWavelenLimits(
            None, None, None)
        bandpass = Bandpass(wavelen=filtre_trans.wavelen, sb=filtre_trans.sb)
        flatSed = Sed()
        flatSed.setFlatSED(wavelen_min, wavelen_max, wavelen_step)
        flux0 = np.power(10., -0.4 * mbZ)
        flatSed.multiplyFluxNorm(flux0)
        photParams = PhotometricParameters(bandpass=filtre)
        counts = flatSed.calcADU(
            bandpass, photParams=photParams)  #number of counts for exptime
        self.data['zp'][filtre] = mbZ
        #print 'hello',counts/self.photParams.exptime
        self.data['counts_zp'][filtre] = counts / 2. * photParams.exptime
Пример #10
0
def setM5(m5target, skysed, totalBandpass, hardware, photParams, FWHMeff=None):
    """
    Take an SED representing the sky and normalize it so that
    m5 (the magnitude at which an object is detected in this
    bandpass at 5-sigma) is set to some specified value.

    The 5-sigma limiting magnitude (m5) for an observation is
    determined by a combination of the telescope and camera parameters
    (such as diameter of the mirrors and the readnoise) together with the
    sky background. This method (setM5) scales a provided sky background
    Sed so that an observation would have a target m5 value, for the
    provided hardware parameters. Using the resulting Sed in the
    'calcM5' method will return this target value for m5.

    @param [in] the desired value of m5

    @param [in] skysed is an instantiation of the Sed class representing
    sky emission

    @param [in] totalBandpass is an instantiation of the Bandpass class
    representing the total throughput of the telescope (instrumentation
    plus atmosphere)

    @param [in] hardware is an instantiation of the Bandpass class representing
    the throughput due solely to instrumentation.

    @param [in] photParams is an instantiation of the
    PhotometricParameters class that carries details about the
    photometric response of the telescope.

    @param [in] FWHMeff in arcseconds

    @param [out] returns an instantiation of the Sed class that is the skysed renormalized
    so that m5 has the desired value.

    Note that the returned SED will be renormalized such that calling the method
    self.calcADU(hardwareBandpass) on it will yield the number of counts per square
    arcsecond in a given bandpass.
    """

    #This is based on the LSST SNR document (v1.2, May 2010)
    #www.astro.washington.edu/users/ivezic/Astr511/LSST_SNRdoc.pdf

    if FWHMeff is None:
        FWHMeff = LSSTdefaults().FWHMeff('r')

    skyCountsTarget = calcSkyCountsPerPixelForM5(m5target,
                                                 totalBandpass,
                                                 FWHMeff=FWHMeff,
                                                 photParams=photParams)

    skySedOut = Sed(wavelen=numpy.copy(skysed.wavelen),
                    flambda=numpy.copy(skysed.flambda))

    skyCounts = skySedOut.calcADU(hardware, photParams=photParams) \
                    * photParams.platescale * photParams.platescale
    skySedOut.multiplyFluxNorm(skyCountsTarget / skyCounts)

    return skySedOut
def setM5(m5target, skysed, totalBandpass, hardware,
          photParams,
          FWHMeff = None):
    """
    Take an SED representing the sky and normalize it so that
    m5 (the magnitude at which an object is detected in this
    bandpass at 5-sigma) is set to some specified value.

    The 5-sigma limiting magnitude (m5) for an observation is
    determined by a combination of the telescope and camera parameters
    (such as diameter of the mirrors and the readnoise) together with the
    sky background. This method (setM5) scales a provided sky background
    Sed so that an observation would have a target m5 value, for the
    provided hardware parameters. Using the resulting Sed in the
    'calcM5' method will return this target value for m5.

    @param [in] the desired value of m5

    @param [in] skysed is an instantiation of the Sed class representing
    sky emission

    @param [in] totalBandpass is an instantiation of the Bandpass class
    representing the total throughput of the telescope (instrumentation
    plus atmosphere)

    @param [in] hardware is an instantiation of the Bandpass class representing
    the throughput due solely to instrumentation.

    @param [in] photParams is an instantiation of the
    PhotometricParameters class that carries details about the
    photometric response of the telescope.

    @param [in] FWHMeff in arcseconds

    @param [out] returns an instantiation of the Sed class that is the skysed renormalized
    so that m5 has the desired value.

    Note that the returned SED will be renormalized such that calling the method
    self.calcADU(hardwareBandpass) on it will yield the number of counts per square
    arcsecond in a given bandpass.
    """

    #This is based on the LSST SNR document (v1.2, May 2010)
    #www.astro.washington.edu/users/ivezic/Astr511/LSST_SNRdoc.pdf

    if FWHMeff is None:
        FWHMeff = LSSTdefaults().FWHMeff('r')

    skyCountsTarget = calcSkyCountsPerPixelForM5(m5target, totalBandpass, FWHMeff=FWHMeff,
                                             photParams=photParams)

    skySedOut = Sed(wavelen=numpy.copy(skysed.wavelen),
                    flambda=numpy.copy(skysed.flambda))

    skyCounts = skySedOut.calcADU(hardware, photParams=photParams) \
                    * photParams.platescale * photParams.platescale
    skySedOut.multiplyFluxNorm(skyCountsTarget/skyCounts)

    return skySedOut
Пример #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 _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)
Пример #15
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
Пример #16
0
def calcADUwrapper(sedName=None,
                   magNorm=None,
                   redshift=None,
                   internalAv=None,
                   internalRv=None,
                   galacticAv=None,
                   galacticRv=None,
                   bandpass=None):
    """
    Read in an SED and calculat the number of ADU produced by that SED in a specified bandpass

    Parameters
    ----------
    sedName is a string specifying the file name of the SED

    magNorm is the normalizing magnitude of the SED in the imsimBandpass

    redshift is the redshift of the SED

    internalAv is the Av due to internal dust of the source (if a galaxy)

    internalRv is the Rv due to internal dust of the source (if a galaxy)

    galacticAv is the Av due to Milky Way dust between observer and source

    galacticRv is the Rv due to Milky Way dust between observer and source

    bandpass is an intantiation of Bandpass representing the band in which the ADUs are measured

    Returns
    -------
    A float representing the number of ADUs measured in the bandpass
    """

    imsimband = Bandpass()
    imsimband.imsimBandpass()
    sed = Sed()
    sed.readSED_flambda(sedName)
    fNorm = sed.calcFluxNorm(magNorm, imsimband)
    sed.multiplyFluxNorm(fNorm)
    if internalAv is not None and internalRv is not None:
        if internalAv != 0.0 and internalRv != 0.0:
            a_int, b_int = sed.setupCCM_ab()
            sed.addDust(a_int, b_int, A_v=internalAv, R_v=internalRv)

    if redshift is not None and redshift != 0.0:
        sed.redshiftSED(redshift, dimming=True)

    a_int, b_int = sed.setupCCM_ab()
    sed.addDust(a_int, b_int, A_v=galacticAv, R_v=galacticRv)

    adu = sed.calcADU(bandpass, photParams=PhotometricParameters())

    return adu
Пример #17
0
 def Get_m5(self,filtre,mag_SN,msky,photParams,FWHMeff):
     
     wavelen_min, wavelen_max, wavelen_step=self.transmission.lsst_system[filtre].getWavelenLimits(None,None,None)
             
     flatSed = Sed()
     flatSed.setFlatSED(wavelen_min, wavelen_max, wavelen_step)
     flux0=np.power(10.,-0.4*msky)
     flatSed.multiplyFluxNorm(flux0)
     m5_calc=SignalToNoise.calcM5(flatSed,self.transmission.lsst_atmos_aerosol[filtre],self.transmission.lsst_system[filtre],photParams=photParams,FWHMeff=FWHMeff)
     snr_m5_through,gamma_through=SignalToNoise.calcSNR_m5(mag_SN,self.transmission.lsst_atmos_aerosol[filtre],m5_calc,photParams)
     
     return m5_calc,snr_m5_through
Пример #18
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
Пример #19
0
    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)
Пример #20
0
    def Calc_Sky(self, paper, infos, transmission):

        Diameter = 6.5  #m
        Deltat = 30  #s
        platescale = 0.2  #arsec
        gain = 2.3

        for filtre in self.filters:

            filtre_trans = transmission.lsst_system[filtre]
            wavelen_min, wavelen_max, wavelen_step = filtre_trans.getWavelenLimits(
                None, None, None)
            photParams = PhotometricParameters()
            #photParams._exptime=30.

            bandpass = Bandpass(wavelen=filtre_trans.wavelen,
                                sb=filtre_trans.sb)

            infos['Skyb'][filtre] = 5455 * np.power(
                Diameter / 6.5, 2.) * np.power(Deltat / 30., 2.) * np.power(
                    platescale, 2.) * np.power(
                        10., 0.4 *
                        (25. -
                         infos['mbsky'][filtre])) * infos['Sigmab'][filtre]

            Zb = 181.8 * np.power(Diameter / 6.5, 2.) * infos['Tb'][filtre]
            mbZ = 25. + 2.5 * np.log10(Zb)
            flatSed = Sed()
            flatSed.setFlatSED(wavelen_min, wavelen_max, wavelen_step)
            flux0 = np.power(10., -0.4 * mbZ)
            flatSed.multiplyFluxNorm(flux0)
            counts = flatSed.calcADU(
                bandpass, photParams=photParams)  #number of counts for exptime
            infos['mb_Z'][filtre] = mbZ
            infos['counts_mb_Z'][filtre] = counts / photParams.exptime

            flatSedb = Sed()
            flatSedb.setFlatSED(wavelen_min, wavelen_max, wavelen_step)
            flux0b = np.power(10., -0.4 * infos['mbsky'][filtre])
            flatSedb.multiplyFluxNorm(flux0b)
            FWHMeff = SignalToNoise.FWHMgeom2FWHMeff(paper['Seeing'][filtre])
            #FWHMeff = paper['Seeing'][filtre]
            #m5_calc=SignalToNoise.calcM5(flatSedb,transmission.lsst_atmos[filtre],transmission.lsst_system[filtre],photParams=photParams,FWHMeff=FWHMeff)
            m5_calc = SignalToNoise.calcM5(
                flatSedb,
                transmission.lsst_atmos[filtre],
                transmission.lsst_system[filtre],
                photParams=photParams,
                FWHMeff=self.paper['FWHMeff'][filtre])
            infos['fiveSigmaDepth'][filtre] = m5_calc
Пример #21
0
    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)
Пример #22
0
    def mag_to_flux_e_sec(self, mag, band, exptime, nexp):
        """
        Mag to flux (in photoelec/sec) conversion

        Parameters
        --------------
        mag : float
          input magnitudes
        band : str
          input bands
        exptime : float
          input exposure times
        nexp: int
          number of exposures

        Returns
        ----------
        counts : float
           number of ADU counts
        e_per_sec : float
           flux in photoelectron per sec.

        """
        if not hasattr(mag, '__iter__'):
            wavelen_min, wavelen_max, wavelen_step = self.atmosphere[
                band].getWavelenLimits(None, None, None)
            sed = Sed()
            sed.setFlatSED()

            flux0 = sed.calcFluxNorm(mag, self.atmosphere[band])
            sed.multiplyFluxNorm(flux0)

            photParams = PhotometricParameters(exptime=exptime, nexp=nexp)

            counts = sed.calcADU(bandpass=self.atmosphere[band],
                                 photParams=photParams)
            e_per_sec = counts

            # counts per sec
            e_per_sec /= (exptime * nexp)
            # conversion to pe
            e_per_sec *= photParams.gain
            return counts, e_per_sec
        else:
            r = []
            for m, b, expt, nexpos in zip(mag, band, exptime, nexp):
                counts, flux_e = self.mag_to_flux_e_sec(m, b, expt, nexpos)
                r.append((counts, flux_e))
            return np.asarray(r)
    def _calcSingleGalSimSed(self, sedName, zz, iAv, iRv, gAv, gRv, norm):
        """
        correct the SED for redshift, dust, etc.  Return an Sed object as defined in
        sims_photUtils/../../Sed.py
        """
        if _is_null(sedName):
            return None
        sed = Sed()
        sed.readSED_flambda(os.path.join(self.sedDir, sedName))
        imsimband = Bandpass()
        imsimband.imsimBandpass()
        # normalize the SED
        # Consulting the file sed.py in GalSim/galsim/ it appears that GalSim expects
        # its SEDs to ultimately be in units of ergs/nm so that, when called, they can
        # be converted to photons/nm (see the function __call__() and the assignment of
        # self._rest_photons in the __init__() of galsim's sed.py file).  Thus, we need
        # to read in our SEDs, normalize them, and then multiply by the exposure time
        # and the effective area to get from ergs/s/cm^2/nm to ergs/nm.
        #
        # The gain parameter should convert between photons and ADU (so: it is the
        # traditional definition of "gain" -- electrons per ADU -- multiplied by the
        # quantum efficiency of the detector).  Because we fold the quantum efficiency
        # of the detector into our total_[u,g,r,i,z,y].dat bandpass files
        # (see the readme in the THROUGHPUTS_DIR/baseline/), we only need to multiply
        # by the electrons per ADU gain.
        #
        # We will take these parameters from an instantiation of the PhotometricParameters
        # class (which can be reassigned by defining a daughter class of this class)
        #
        fNorm = sed.calcFluxNorm(norm, imsimband)
        sed.multiplyFluxNorm(fNorm)

        # apply dust extinction (internal)
        if iAv != 0.0 and iRv != 0.0:
            a_int, b_int = sed.setupCCM_ab()
            sed.addDust(a_int, b_int, A_v=iAv, R_v=iRv)

        # 22 June 2015
        # apply redshift; there is no need to apply the distance modulus from
        # sims/photUtils/CosmologyWrapper; magNorm takes that into account
        # however, magNorm does not take into account cosmological dimming
        if zz != 0.0:
            sed.redshiftSED(zz, dimming=True)

        # apply dust extinction (galactic)
        if gAv != 0.0 and gRv != 0.0:
            a_int, b_int = sed.setupCCM_ab()
            sed.addDust(a_int, b_int, A_v=gAv, R_v=gRv)
        return sed
Пример #24
0
def calcADUwrapper(sedName=None, magNorm=None, redshift=None, internalAv=None, internalRv=None,
                   galacticAv=None, galacticRv=None, bandpass=None):
    """
    Read in an SED and calculat the number of ADU produced by that SED in a specified bandpass

    Parameters
    ----------
    sedName is a string specifying the file name of the SED

    magNorm is the normalizing magnitude of the SED in the imsimBandpass

    redshift is the redshift of the SED

    internalAv is the Av due to internal dust of the source (if a galaxy)

    internalRv is the Rv due to internal dust of the source (if a galaxy)

    galacticAv is the Av due to Milky Way dust between observer and source

    galacticRv is the Rv due to Milky Way dust between observer and source

    bandpass is an intantiation of Bandpass representing the band in which the ADUs are measured

    Returns
    -------
    A float representing the number of ADUs measured in the bandpass
    """

    imsimband = Bandpass()
    imsimband.imsimBandpass()
    sed = Sed()
    sed.readSED_flambda(sedName)
    fNorm = sed.calcFluxNorm(magNorm, imsimband)
    sed.multiplyFluxNorm(fNorm)
    if internalAv is not None and internalRv is not None:
        if internalAv != 0.0 and internalRv != 0.0:
            a_int, b_int = sed.setupCCM_ab()
            sed.addDust(a_int, b_int, A_v=internalAv, R_v=internalRv)

    if redshift is not None and redshift != 0.0:
        sed.redshiftSED(redshift, dimming=True)

    a_int, b_int = sed.setupCCM_ab()
    sed.addDust(a_int, b_int, A_v=galacticAv, R_v=galacticRv)

    adu = sed.calcADU(bandpass, photParams=PhotometricParameters())

    return adu
Пример #25
0
    def ZP_filtre(self, filtre):
        """
        ZP_filtre() : Compute zero point in filter band
        - platescale is 0.2 arcsec per pixel
        
        Tool function implemented by Phillie Gris (IN2P3)
        
        """
        # extract parameters from lsst_sims
        photParams = PhotometricParameters(bandpass=filtre)
        # compute Diameter in meters : D=2*R = 2*sqrt(S/pi)
        Diameter = 2. * np.sqrt(
            photParams.effarea * 1.e-4 / np.pi)  # diameter in meter
        # AB flux is 3.6307805477e-20 erg/cm2/s/Hz or 3.6307805477e-16 erg/m2/s/Hz
        #   or 3.6307e-23 J/m2/s/Hz, h=6.626e-34 J.s
        # What is the meaning of this Cte ????
        # especcialy what is 1e36 ?
        Cte = 3631. * np.pi * Diameter**2 * 2. * photParams.exptime / 4 / h / 1.e36
        #print('Telescope::ZP_filtre: hello Cte=',Cte, ' Diam=',Diameter, 'h=',h,' exptime=',photParams.exptime)

        # What is the meaning of Skyb ?????
        self.data['Skyb'][filtre] = Cte * np.power(
            Diameter / 6.5, 2.) * np.power(
                2. * photParams.exptime / 30., 2.) * np.power(
                    photParams.platescale, 2.) * np.power(
                        10., 0.4 *
                        (25. - self.mag_sky[filtre])) * self.Sigmab[filtre]

        #What is the meaning of Sigmab, Tb, Zb   such Zb is used to calculate zero point
        Zb = 181.8 * np.power(Diameter / 6.5, 2.) * self.Tb[filtre]
        mbZ = 25. + 2.5 * np.log10(Zb)
        #filter without atmosphere
        filtre_trans = self.system[filtre]
        wavelen_min, wavelen_max, wavelen_step = filtre_trans.getWavelenLimits(
            None, None, None)

        bandpass = Bandpass(wavelen=filtre_trans.wavelen, sb=filtre_trans.sb)

        flatSed = Sed()
        flatSed.setFlatSED(wavelen_min, wavelen_max, wavelen_step)
        flux0 = np.power(10., -0.4 * mbZ)
        flatSed.multiplyFluxNorm(flux0)
        photParams = PhotometricParameters(bandpass=filtre)
        counts = flatSed.calcADU(
            bandpass, photParams=photParams)  #number of counts for exptime
        self.data['zp'][filtre] = mbZ
        #print('Telescope::ZP_filtre hello',counts/self.photParams.exptime)
        self.data['counts_zp'][filtre] = counts / 2. * photParams.exptime
Пример #26
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)
Пример #27
0
def make_response_func(magnorm=16., filename='starSED/wDs/bergeron_14000_85.dat_14200.gz',
                       savefile='gaia_response.npz', noise=1, count_min=8.,
                       bluecut=700., redcut=650):
    """
    Declare some stars as "standards" and build a simple GAIA response function?

    Multiply GAIA observations by response function to get spectra in flambda units.
    """
    imsimBand = Bandpass()
    imsimBand.imsimBandpass()

    sed_dir = getPackageDir('sims_sed_library')
    filepath = os.path.join(sed_dir, filename)
    wd = Sed()
    wd.readSED_flambda(filepath)
    # Let's just use a flat spectrum
    wd.setFlatSED()
    fNorm = wd.calcFluxNorm(magnorm, imsimBand)
    wd.multiplyFluxNorm(fNorm)
    red_wd = copy.copy(wd)
    blue_wd = copy.copy(wd)
    gaia_obs = SED2GAIA(wd, noise=noise)
    red_wd.resampleSED(wavelen_match = gaia_obs['RP_wave'])
    blue_wd.resampleSED(wavelen_match = gaia_obs['BP_wave'])
    if noise == 1:
        red_response = red_wd.flambda / gaia_obs['noisySpec'][0]['RPNoisySpec']
        blue_response = blue_wd.flambda / gaia_obs['noisySpec'][0]['BPNoisySpec']
        too_low = np.where(gaia_obs['noisySpec'][0]['RPNoisySpec'] < count_min)
        red_response[too_low] = 0
        too_low = np.where(gaia_obs['noisySpec'][0]['BPNoisySpec'] < count_min)
        blue_response[too_low] = 0
    elif noise == 0:
        red_response = red_wd.flambda / gaia_obs['noiseFreeSpec']['RPNoiseFreeSpec']
        blue_response = blue_wd.flambda / gaia_obs['noiseFreeSpec']['BPNoiseFreeSpec']
        too_low = np.where(gaia_obs['noiseFreeSpec']['RPNoiseFreeSpec'] < count_min)
        red_response[too_low] = 0
        too_low = np.where(gaia_obs['noiseFreeSpec']['BPNoiseFreeSpec'] < count_min)
        blue_response[too_low] = 0

    blue_response[np.where(gaia_obs['BP_wave'] > bluecut)] = 0.
    red_response[np.where(gaia_obs['RP_wave'] < redcut)] = 0.

    # XXX check the mags of the original WD and the blue and red WD.

    np.savez(savefile, red_response=red_response, blue_response=blue_response,
             red_wavelen=gaia_obs['RP_wave'], blue_wavelen=gaia_obs['BP_wave'])
Пример #28
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)
Пример #29
0
    def Calc_m5(self, filtre):
        """
        Calc_m5(filtre):
        
        Compute m5 or SNR at five sigma
        Tool function implemented by Phillie Gris (IN2P3)
        
        """
        # get telescope passband (no atmosphere)
        filtre_trans = self.system[filtre]
        wavelen_min, wavelen_max, wavelen_step = filtre_trans.getWavelenLimits(
            None, None, None)

        bandpass = Bandpass(wavelen=filtre_trans.wavelen, sb=filtre_trans.sb)
        # create a Flat sed S_nu from the sky brightness magnitude
        flatSedb = Sed()
        flatSedb.setFlatSED(wavelen_min, wavelen_max, wavelen_step)
        flux0b = np.power(10., -0.4 * self.mag_sky[filtre])
        flatSedb.multiplyFluxNorm(flux0b)

        # Get LSST photometric parameters
        photParams = PhotometricParameters(bandpass=filtre)
        norm = photParams.platescale**2 / 2. * photParams.exptime / photParams.gain

        # Use LSST sims (SignalToNoise) to calculate M5 with atmosphere or without atmosphere
        if self.atmos:
            self.data['m5'][filtre] = SignalToNoise.calcM5(
                flatSedb,
                self.atmosphere[filtre],
                self.system[filtre],
                photParams=photParams,
                FWHMeff=self.FWHMeff[filtre])
            adu_int = flatSedb.calcADU(bandpass=self.atmosphere[filtre],
                                       photParams=photParams)
            self.data['flux_sky'][filtre] = adu_int * norm
        else:
            self.data['m5'][filtre] = SignalToNoise.calcM5(
                flatSedb,
                self.system[filtre],
                self.system[filtre],
                photParams=photParams,
                FWHMeff=self.FWHMeff[filtre])
            adu_int = flatSedb.calcADU(bandpass=self.system[filtre],
                                       photParams=photParams)
            self.data['flux_sky'][filtre] = adu_int * norm
Пример #30
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)
Пример #31
0
    def CalcMyABMagnitudesError_filter(self, band, SkyBrightnessMag, FWHMGeom):
        """
        CalcMyABMagnitudesError_filter(self,band,SkyBrightnessMag,FWHMGeom)
        
        - author : Sylvie Dagoret-Campagne
        - affiliation : LAL/IN2P3/CNRS/FRANCE
        - date   : July 5th 2018
        
        Calculate magnitude errors for one band.
        
        Input args:
        - band : filter band
        - SkyBrighnessMag : Sky Brighness Magnitude in the band
        - FWHMGeom : Geometrical PSF in the band
        
        """

        filtre_atm = self.lsst_atmos[band]
        filtre_syst = self.lsst_system[band]

        wavelen_min, wavelen_max, wavelen_step = filtre_syst.getWavelenLimits(
            None, None, None)

        #calculation of effective PSF
        FWHMeff = SignalToNoise.FWHMgeom2FWHMeff(FWHMGeom)

        photParams = PhotometricParameters(bandpass=band)

        # create a Flat sed S_nu from the sky brightness magnitude
        skysed = Sed()
        skysed.setFlatSED(wavelen_min, wavelen_max, wavelen_step)
        flux0b = np.power(10., -0.4 * SkyBrightnessMag)
        skysed.multiplyFluxNorm(flux0b)

        #calcMagError filled according doc
        mag_err = SignalToNoise.calcMagError_sed(self.sed,
                                                 filtre_atm,
                                                 skysed,
                                                 filtre_syst,
                                                 photParams,
                                                 FWHMeff,
                                                 verbose=False)

        return mag_err
Пример #32
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)
Пример #33
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)
Пример #34
0
    def get_zp(self, what, band):
        """
        decorator get zero points
        formula used here are extracted from LSE-40

        Parameters
        ---------------
        what: str
          parameter to estimate
        band: str
          filter

        """
        photParams = PhotometricParameters(bandpass=band)
        Diameter = 2. * np.sqrt(
            photParams.effarea * 1.e-4 / np.pi)  # diameter in meter
        Cte = 3631. * np.pi * Diameter**2 * 2. * photParams.exptime / 4 / h / 1.e36

        self.data['Skyb'][band] = Cte*np.power(Diameter/6.5, 2.)\
            * np.power(2.*photParams.exptime/30., 2.)\
            * np.power(photParams.platescale, 2.)\
            * 10.**0.4*(25.-self.mag_sky(band))\
            * self.Sigmab(band)

        Zb = 181.8 * np.power(Diameter / 6.5, 2.) * self.Tb(band)
        mbZ = 25. + 2.5 * np.log10(Zb)
        filtre_trans = self.system[band]
        wavelen_min, wavelen_max, wavelen_step = filtre_trans.getWavelenLimits(
            None, None, None)
        bandpass = Bandpass(wavelen=filtre_trans.wavelen, sb=filtre_trans.sb)
        flatSed = Sed()
        flatSed.setFlatSED(wavelen_min, wavelen_max, wavelen_step)
        flux0 = np.power(10., -0.4 * mbZ)
        flatSed.multiplyFluxNorm(flux0)
        photParams = PhotometricParameters(bandpass=band)
        # number of counts for exptime
        counts = flatSed.calcADU(bandpass, photParams=photParams)
        self.data['zp'][band] = mbZ
        self.data['counts_zp'][band] = counts / 2. * photParams.exptime
Пример #35
0
    def testStellarPhotometricUncertainties(self):
        """
        Test in the case of a catalog of stars
        """
        lsstDefaults = LSSTdefaults()
        starDB = testStarsDBObj(driver=self.driver,
                                host=self.host,
                                database=self.dbName)
        starCat = testStarCatalog(starDB, obs_metadata=self.obs_metadata)

        ct = 0
        for line in starCat.iter_catalog():
            starSed = Sed()
            starSed.readSED_flambda(
                os.path.join(getPackageDir('sims_sed_library'),
                             defaultSpecMap[line[14]]))
            imsimband = Bandpass()
            imsimband.imsimBandpass()
            fNorm = starSed.calcFluxNorm(line[15], imsimband)
            starSed.multiplyFluxNorm(fNorm)

            aV = np.float(line[16])
            a_int, b_int = starSed.setupCCMab()
            starSed.addCCMDust(a_int, b_int, A_v=aV)

            for i in range(len(self.bandpasses)):
                controlSigma = calcMagError_sed(
                    starSed,
                    self.totalBandpasses[i],
                    self.skySeds[i],
                    self.hardwareBandpasses[i],
                    FWHMeff=lsstDefaults.FWHMeff(self.bandpasses[i]),
                    photParams=PhotometricParameters())

                testSigma = line[8 + i]
                self.assertAlmostEqual(controlSigma, testSigma, 4)
                ct += 1
        self.assertGreater(ct, 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)
Пример #37
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)
Пример #38
0
    def Calc_m5(self, filtre):

        filtre_trans = self.throughputs.system[filtre]
        wavelen_min, wavelen_max, wavelen_step = filtre_trans.getWavelenLimits(
            None, None, None)

        bandpass = Bandpass(wavelen=filtre_trans.wavelen, sb=filtre_trans.sb)

        flatSedb = Sed()
        flatSedb.setFlatSED(wavelen_min, wavelen_max, wavelen_step)
        flux0b = np.power(10., -0.4 * self.mag_sky[filtre])
        flatSedb.multiplyFluxNorm(flux0b)
        if self.atmos:
            self.data['m5'][filtre] = SignalToNoise.calcM5(
                flatSedb,
                self.throughputs.atmosphere[filtre],
                self.throughputs.system[filtre],
                photParams=self.photParams,
                FWHMeff=self.FWHMeff[filtre])
            adu_int = flatSedb.calcADU(
                bandpass=self.throughputs.atmosphere[filtre],
                photParams=self.photParams)
            self.data['flux_sky'][
                filtre] = adu_int * self.pixel_area / self.expTime[
                    filtre] / self.gain
        else:
            self.data['m5'][filtre] = SignalToNoise.calcM5(
                flatSedb,
                self.throughputs.system[filtre],
                self.throughputs.system[filtre],
                photParams=self.photParams,
                FWHMeff=self.FWHMeff[filtre])
            adu_int = flatSedb.calcADU(
                bandpass=self.throughputs.system[filtre],
                photParams=self.photParams)
            self.data['flux_sky'][
                filtre] = adu_int * self.pixel_area / self.expTime[
                    filtre] / self.gain
Пример #39
0
def calcADUwrapper(sedName=None, magNorm=None, redshift=None, internalAv=None, internalRv=None,
                   galacticAv=None, galacticRv=None, bandpass=None):

    imsimband = Bandpass()
    imsimband.imsimBandpass()
    sed = Sed()
    sed.readSED_flambda(sedName)
    fNorm = sed.calcFluxNorm(magNorm, imsimband)
    sed.multiplyFluxNorm(fNorm)
    if internalAv is not None and internalRv is not None:
        if internalAv != 0.0 and internalRv != 0.0:
            a_int, b_int = sed.setupCCMab()
            sed.addCCMDust(a_int, b_int, A_v=internalAv, R_v=internalRv)
    
    if redshift is not None and redshift != 0.0:
        sed.redshiftSED(redshift, dimming=True)
    
    a_int, b_int = sed.setupCCMab()
    sed.addCCMDust(a_int, b_int, A_v=galacticAv, R_v=galacticRv)
    
    adu = sed.calcADU(bandpass, photParams=PhotometricParameters())
    
    return adu
Пример #40
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)
Пример #41
0
    def CalcMyABMagnitudesErrors(self):
        """
        CalcMyABMagnitudesErrors(self)
        
        - author : Sylvie Dagoret-Campagne
        - affiliation : LAL/IN2P3/CNRS/FRANCE
        - date   : July 4th 2018
        
        Calculate magnitude errors for all bands
        
        """
        all_magABErr = []

        for i, band in enumerate(self.filterlist):

            filtre_atm = self.lsst_atmos[band]
            filtre_syst = self.lsst_system[band]

            wavelen_min, wavelen_max, wavelen_step = filtre_syst.getWavelenLimits(
                None, None, None)

            photParams = PhotometricParameters(bandpass=band)
            FWHMeff = self.data['FWHMeff'][band]

            # create a Flat sed S_nu from the sky brightness magnitude
            skysed = Sed()
            skysed.setFlatSED(wavelen_min, wavelen_max, wavelen_step)
            flux0b = np.power(10., -0.4 * self.mag_sky[band])
            skysed.multiplyFluxNorm(flux0b)

            #calcMagError filled according doc
            magerr=SignalToNoise.calcMagError_sed( \
                self.sed,filtre_atm,skysed,filtre_syst,photParams,FWHMeff,verbose=False)

            all_magABErr.append(magerr)
        return np.array(all_magABErr)
Пример #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)
Пример #43
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)
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. 
star.multiplyFluxNorm(fluxnorm)

# Try the magnitude calculation again. 
mag = star.calcMag(rband)
print "After scaling, magnitude of SED is now %.4f (desired magnitude was %.4f)" %(mag, mag_desired)

# And let's calculate what the expected photon counts for LSST would be.
counts = star.calcADU(rband, expTime=30)
print "This would correspond to roughly %f counts in the LSST focal plane, in a 30s exposure." %(counts)

# For fun, let's see what else can happen.

ebv = 0.5
print ""
print "Let's try adding %.2f E(B-V) dust extinction to this star." %(ebv)
a, b = star.setupCCMab()
# 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])
    
Пример #46
0
    def _quiescentMagnitudeGetter(self, bandpassDict, columnNameList, bandpassTag='lsst'):
        """
        Method that actually does the work calculating magnitudes for solar system objects.

        Because solar system objects have no dust extinction, this method works by loading
        each unique Sed once, normalizing it, calculating its magnitudes in the desired
        bandpasses, and then storing the normalizing magnitudes and the bandpass magnitudes
        in a dict.  Magnitudes for subsequent objects with identical Seds will be calculated
        by adding an offset to the magnitudes.  The offset is determined by comparing normalizing
        magnitues.

        @param [in] bandpassDict is an instantiation of BandpassDict representing the bandpasses
        to be integrated over

        @param [in] columnNameList is a list of the names of the columns being calculated
        by this getter

        @param [in] bandpassTag (optional) is a string indicating the name of the bandpass system
        (i.e. 'lsst', 'sdss', etc.).  This is in case the user wants to calculate the magnitudes
        in multiple systems simultaneously.  In that case, the dict will store magnitudes for each
        Sed in each magnitude system separately.

        @param [out] a numpy array of magnitudes corresponding to bandpassDict.
        """

        # figure out which of these columns we are actually calculating
        indices = [ii for ii, name in enumerate(columnNameList)
                   if name in self._actually_calculated_columns]

        if len(indices) == len(columnNameList):
            indices = None

        if not hasattr(self, '_ssmMagDict'):
            self._ssmMagDict = {}
            self._ssmMagNormDict = {}
            self._file_dir = getPackageDir('sims_sed_library')
            self._spec_map = defaultSpecMap
            self._normalizing_bandpass = Bandpass()
            self._normalizing_bandpass.imsimBandpass()

        sedNameList = self.column_by_name('sedFilename')
        magNormList = self.column_by_name('magNorm')

        if len(sedNameList)==0:
            # need to return something when InstanceCatalog goes through
            # it's "dry run" to determine what columns are required from
            # the database
            return np.zeros((len(bandpassDict.keys()),0))

        magListOut = []

        for sedName, magNorm in zip(sedNameList, magNormList):
            magTag = bandpassTag+'_'+sedName
            if sedName not in self._ssmMagNormDict or magTag not in self._ssmMagDict:
                dummySed = Sed()
                dummySed.readSED_flambda(os.path.join(self._file_dir, self._spec_map[sedName]))
                fnorm = dummySed.calcFluxNorm(magNorm, self._normalizing_bandpass)
                dummySed.multiplyFluxNorm(fnorm)
                magList = bandpassDict.magListForSed(dummySed, indices=indices)
                self._ssmMagDict[magTag] = magList
                self._ssmMagNormDict[sedName] = magNorm
            else:
                dmag = magNorm - self._ssmMagNormDict[sedName]
                magList = self._ssmMagDict[magTag] + dmag
            magListOut.append(magList)

        return np.array(magListOut).transpose()
Пример #47
0
response = gaia_response(restore_file='gaia_response.npz')
# response = gaia_response(restore_file='gaia_response_nonoise.npz')


filename = 'starSED/wDs/bergeron_14000_85.dat_14200.gz'
imsimBand = Bandpass()
imsimBand.imsimBandpass()

sed_dir = getPackageDir('sims_sed_library')
filepath = os.path.join(sed_dir, filename)
wd = Sed()
wd.readSED_flambda(filepath)
magnorm = 16
fNorm = wd.calcFluxNorm(magnorm, imsimBand)
wd.multiplyFluxNorm(fNorm)

throughPath = os.path.join(getPackageDir('throughputs'), 'baseline')
lsstKeys = ['u', 'g', 'r', 'i', 'z', 'y']
# lsstKeys = ['r']
bps = {}
for key in lsstKeys:
    bp = np.loadtxt(os.path.join(throughPath, 'total_'+key+'.dat'),
                    dtype=zip(['wave', 'trans'], [float]*2))
    bpTemp = Bandpass()
    good = np.where(bp['trans'] > 0.)
    bpTemp.setBandpass(bp['wave'], bp['trans'], wavelen_min=bp['wave'][good].min(),
                       wavelen_max=bp['wave'][good].max())
    bps[key] = bpTemp

# Generate a GAIA observation
#  same wavelength range we can just calculate a/b once, and this is slow)

a, b = stars[starskeys[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(starskeys), dtype="float")
mags2 = n.empty(len(starskeys), dtype="float")
sedlist = []
for i in range(len(starskeys)):
    # make a copy of the original SED *if* you want to 'reuse' the SED for multiple magnitude
    # calculations with various fluxnorms and dust applications (otherwise just use the object
    # you instantiated above)
    tmpstar = Sed(wavelen=stars[starskeys[i]].wavelen, flambda=stars[starskeys[i]].flambda)
    tmpstar.addCCMDust(a, b, ebv=ebv[i])
    tmpstar.multiplyFluxNorm(fluxnorm[i])
    mags[i] = tmpstar.calcMag(rband)
    # This is for showing an example of the manyMagCalc function on bandpass
    sedlist.append(tmpstar)


# Now, pretend we're actually wanting to calculate the magnitude in multiple bandpasses.
# (ignore the part that uses exampleBandpass.dat as the source .. you would replace that with
#  rootdir + "total_" + filter where filter is a member of lsstfilterlist
lsstfilterlist = ["u", "g", "r", "i", "z", "y"]
lsst = {}
rootdir = "./"
for filter in lsstfilterlist:
    lsst[filter] = Bandpass()
    lsst[filter].readThroughput(rootdir + "exampleBandpass.dat")
    # you have to do this now - sbToPhi to use the multi-mag calc
Пример #49
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)
    def test_mixed_stars(self):
        """
        Here we will test the (somewhat absurd) case of a catalog with two different bandpasses
        (lsst_ and cartoon_) in order to verify that gamma values are being cached correctly
        """

        lsst_u_band = Bandpass()
        lsst_u_band.readThroughput(os.path.join(getPackageDir('throughputs'), 'baseline', 'total_u.dat'))
        lsst_g_band = Bandpass()
        lsst_g_band.readThroughput(os.path.join(getPackageDir('throughputs'), 'baseline', 'total_g.dat'))

        obs = ObservationMetaData(bandpassName=['c_u', 'c_g', 'u', 'g'],
                                  m5=[25.0, 26.0, 15.0, 16.0])
        # make the difference in m5 between the two bandpass systems extreme
        # so that, in the unit test, we can be sure that the correct values
        # are being used for the correct getters

        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, column_outputs=['lsst_u', 'lsst_g',
                                                                 'sigma_lsst_u', 'sigma_lsst_g'])
        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)
            lsst_umag = spectrum.calcMag(lsst_u_band)
            self.assertAlmostEqual(lsst_umag, controlData['lsst_u'][ix], 3)
            lsst_gmag = spectrum.calcMag(lsst_g_band)
            self.assertAlmostEqual(lsst_gmag, controlData['lsst_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)

            lsst_umagError, gamma = calcMagError_m5(lsst_umag, lsst_u_band,
                                                    obs.m5['u'], PhotometricParameters())
            lsst_gmagError, gamma = calcMagError_m5(lsst_gmag, lsst_g_band,
                                                    obs.m5['g'], PhotometricParameters())

            self.assertAlmostEqual(lsst_umagError, controlData['sigma_lsst_u'][ix], 3)
            self.assertAlmostEqual(lsst_gmagError, controlData['sigma_lsst_g'][ix], 3)
            self.assertGreater(np.abs(lsst_umagError-umagError), 0.01)
            self.assertGreater(np.abs(lsst_gmagError-gmagError), 0.01)
    def testObjectPlacement(self):
        """
        Test that GalSim places objects on the correct pixel by drawing
        images, reading them in, and then comparing the flux contained in
        circles of 2 fwhm radii about the object's expected positions with
        the actual expected flux of the objects.
        """
        scratchDir = os.path.join(getPackageDir('sims_GalSimInterface'), 'tests', 'scratchSpace')
        catName = os.path.join(scratchDir, 'placementCatalog.dat')
        imageRoot = os.path.join(scratchDir, 'placementImage')
        dbFileName = os.path.join(scratchDir, 'placementInputCatalog.dat')

        cameraDir = os.path.join(getPackageDir('sims_GalSimInterface'), 'tests', 'cameraData')
        camera = ReturnCamera(cameraDir)
        detector = camera[0]
        imageName = '%s_%s_u.fits' % (imageRoot, detector.getName())

        controlSed = Sed()
        controlSed.readSED_flambda(
                                   os.path.join(getPackageDir('sims_sed_library'),
                                               'flatSED','sed_flat.txt.gz')
                                   )

        uBandpass = Bandpass()
        uBandpass.readThroughput(
                                 os.path.join(getPackageDir('throughputs'),
                                              'baseline','total_u.dat')
                                )

        controlBandpass = Bandpass()
        controlBandpass.imsimBandpass()

        ff = controlSed.calcFluxNorm(self.magNorm, uBandpass)
        controlSed.multiplyFluxNorm(ff)
        a_int, b_int = controlSed.setupCCMab()
        controlSed.addCCMDust(a_int, b_int, A_v=0.1, R_v=3.1)

        nSamples = 5
        numpy.random.seed(42)
        pointingRaList = numpy.random.random_sample(nSamples)*360.0
        pointingDecList = numpy.random.random_sample(nSamples)*180.0 - 90.0
        rotSkyPosList = numpy.random.random_sample(nSamples)*360.0
        fwhmList = numpy.random.random_sample(nSamples)*1.0 + 0.3

        actualCounts = None

        for pointingRA, pointingDec, rotSkyPos, fwhm in \
        zip(pointingRaList, pointingDecList, rotSkyPosList, fwhmList):


            obs = ObservationMetaData(unrefractedRA=pointingRA,
                                      unrefractedDec=pointingDec,
                                      boundType='circle',
                                      boundLength=4.0,
                                      mjd=49250.0,
                                      rotSkyPos=rotSkyPos)

            xDisplacementList = numpy.random.random_sample(nSamples)*60.0-30.0
            yDisplacementList = numpy.random.random_sample(nSamples)*60.0-30.0
            create_text_catalog(obs, dbFileName, xDisplacementList, yDisplacementList,
                                mag_norm=[self.magNorm]*len(xDisplacementList))
            db = placementFileDBObj(dbFileName, runtable='test')
            cat = placementCatalog(db, obs_metadata=obs)
            if actualCounts is None:
                actualCounts = controlSed.calcADU(uBandpass, cat.photParams)

            psf = SNRdocumentPSF(fwhm=fwhm)
            cat.setPSF(psf)
            cat.camera = camera

            cat.write_catalog(catName)
            cat.write_images(nameRoot=imageRoot)

            objRaList = []
            objDecList = []
            with open(catName, 'r') as inFile:
                for line in inFile:
                    if line[0] != '#':
                        words = line.split(';')
                        objRaList.append(numpy.radians(numpy.float(words[2])))
                        objDecList.append(numpy.radians(numpy.float(words[3])))

            objRaList = numpy.array(objRaList)
            objDecList = numpy.array(objDecList)

            self.check_placement(imageName, objRaList, objDecList,
                                [fwhm]*len(objRaList),
                                numpy.array([actualCounts]*len(objRaList)),
                                cat.photParams.gain, detector, camera, obs, epoch=2000.0)

            if os.path.exists(dbFileName):
                os.unlink(dbFileName)
            if os.path.exists(catName):
                os.unlink(catName)
            if os.path.exists(imageName):
                os.unlink(imageName)
Пример #52
0
def get_TotalMags(result, bandpasses=('u','g','r','i','z','y')):
    datadir = os.environ.get("SIMS_SED_LIBRARY_DIR")
    tpath = os.getenv('LSST_THROUGHPUTS_DEFAULT')
    bands = {"u":None, "g":None, "r":None, "i":None, "z":None, "y":None}
    for k in bands:
        bands[k] = Bandpass()
        bands[k].readThroughput(os.path.join(tpath, "total_%s.dat"%k))
    # Set up phi, the wavelength-normalized system response for each filter,
    # for each bandpass for manyMagCalc method.
    bplist = []
    for f in ['u','g','r','i','z','y']:
        bands[f].sbTophi()
        bplist.append(bands[f])
    ids = result['galid']
    diskfile = result['sedFilenameDisk']
    bulgefile = result['sedFilenameBulge']
    agnfile = result['sedFilenameAgn']

    diskmn = result['magNormDisk']
    bulgemn = result['magNormBulge']
    agnmn = result['magNormAgn']

    bulgeAv = result['internalAvBulge']
    diskAv = result['internalAvDisk']

    redshift = result['redshift']

    imsimband = Bandpass()
    imsimband.imsimBandpass()
    sedDict = {}
    retMags = dict([(k, []) for k in bands])
    a_int = None
    b_int = None
    tmpwavelen = None
    for id, df, dm, dav, bf, bm, bav, af, am, z in zip(ids, diskfile, diskmn, diskAv, 
            bulgefile, bulgemn, bulgeAv, agnfile, agnmn, redshift):
        tmpflux = None
        for comp in ((df, dm, dav, 'galaxySED', False), (bf, bm, bav, 'galaxySED', False), (af, am, None, 'agnSED', True)):
        #Zero out the AGN contribution
        #for comp in ((df, dm, dav, 'galaxySED', False), (bf, bm, bav, 'galaxySED', False), (af, 99.99, None, 'agnSED', True)):
            if not comp[0] == u'None':
                if sedDict.has_key(comp[0]):
                    sed = copy.deepcopy(sedDict[comp[0]])
                else:
                    sed = Sed()
                    print os.path.join(datadir,comp[3],comp[0])
                    sed.readSED_flambda(os.path.join(datadir,comp[3],comp[0]))
		    if comp[4]:
		        sed.resampleSED(wavelen_match=tmpwavelen)
                    sedDict[comp[0]] = sed
                if a_int is None:
                    phiarray, dlambda = sed.setupPhiArray(bplist)
                    a_int, b_int = sed.setupCCMab()
		    #Careful, this assumes that a disk or bulge sed is read
		    #before any agn sed
		    tmpwavelen = sed.wavelen
                fNorm = sed.calcFluxNorm(comp[1], imsimband)
                sed.multiplyFluxNorm(fNorm)
                #I guess this assumes rv=3.1??
                if comp[2]:
                    sed.addCCMDust(a_int, b_int, A_v=comp[2])
		wavelenArr=sed.wavelen
		if tmpflux is None:
		    tmpflux = sed.flambda
		else:
	            tmpflux += sed.flambda
	newgal = Sed(wavelen=wavelenArr, flambda=tmpflux)
        #a_mw, b_mw = sed.setupCCMab()
        #sed.addCCMDust(a_mw, b_mw, A_v=mwav)
        newgal.redshiftSED(z, dimming=True)
	newgal.resampleSED(wavelen_match=bplist[0].wavelen)
	newgal.flambdaTofnu()
        mags = newgal.manyMagCalc(phiarray, dlambda)
        for i,k in enumerate(['u','g','r','i','z','y']):
            retMags[k].append(mags[i])
    return retMags
def calcM5(hardware, system, atmos, title="m5"):
    effarea = np.pi * (6.423 / 2.0 * 100.0) ** 2
    photParams = PhotometricParameters(effarea=effarea)
    lsstDefaults = LSSTdefaults()
    darksky = Sed()
    darksky.readSED_flambda(os.path.join("../siteProperties", "darksky.dat"))
    flatSed = Sed()
    flatSed.setFlatSED()
    m5 = {}
    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)
    print title
    print "Filter m5 SourceCounts SkyCounts SkyMag Gamma"
    for f in ("u", "g", "r", "i", "z", "y"):
        print "%s %.2f %.1f %.2f %.2f %.6f" % (f, m5[f], sourceCounts[f], skyCounts[f], skyMag[f], gamma[f])

    # Show what these look like individually (add sky & m5 limits on throughput curves)
    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 with aerosols")
    # Add legend for dark sky.
    myline = mlines.Line2D([], [], color="k", linestyle="-", label="Dark sky AB mags")
    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")
    if title == "Vendor combo":
        title = ""
    plt.title("System total response curves %s" % (title))
    plt.savefig("../plots/system+sky" + title + ".png", format="png", dpi=600)
    return m5
    def testGalaxyPhotometricUncertainties(self):
        """
        Test in the case of a catalog of galaxies
        """
        lsstDefaults = LSSTdefaults()
        phot = PhotometryGalaxies()
        galDB = testGalaxyTileDBObj(driver=self.driver, host=self.host, database=self.dbName)
        galCat = testGalaxyCatalog(galDB, obs_metadata=self.obs_metadata)
        imsimband = Bandpass()
        imsimband.imsimBandpass()
        ct = 0
        for line in galCat.iter_catalog():
            bulgeSedName = line[50]
            diskSedName = line[51]
            agnSedName = line[52]
            magNormBulge = line[53]
            magNormDisk = line[54]
            magNormAgn = line[55]
            avBulge = line[56]
            avDisk = line[57]
            redshift = line[58]

            bulgeSed = Sed()
            bulgeSed.readSED_flambda(os.path.join(lsst.utils.getPackageDir('sims_sed_library'),
                                     defaultSpecMap[bulgeSedName]))
            fNorm=bulgeSed.calcFluxNorm(magNormBulge, imsimband)
            bulgeSed.multiplyFluxNorm(fNorm)

            diskSed = Sed()
            diskSed.readSED_flambda(os.path.join(lsst.utils.getPackageDir('sims_sed_library'),
                                    defaultSpecMap[diskSedName]))
            fNorm = diskSed.calcFluxNorm(magNormDisk, imsimband)
            diskSed.multiplyFluxNorm(fNorm)

            agnSed = Sed()
            agnSed.readSED_flambda(os.path.join(lsst.utils.getPackageDir('sims_sed_library'),
                                   defaultSpecMap[agnSedName]))
            fNorm = agnSed.calcFluxNorm(magNormAgn, imsimband)
            agnSed.multiplyFluxNorm(fNorm)

            a_int, b_int = bulgeSed.setupCCMab()
            bulgeSed.addCCMDust(a_int, b_int, A_v=avBulge)

            a_int, b_int = diskSed.setupCCMab()
            diskSed.addCCMDust(a_int, b_int, A_v=avDisk)

            bulgeSed.redshiftSED(redshift, dimming=True)
            diskSed.redshiftSED(redshift, dimming=True)
            agnSed.redshiftSED(redshift, dimming=True)

            bulgeSed.resampleSED(wavelen_match=self.totalBandpasses[0].wavelen)
            diskSed.resampleSED(wavelen_match=bulgeSed.wavelen)
            agnSed.resampleSED(wavelen_match=bulgeSed.wavelen)

            numpy.testing.assert_almost_equal(bulgeSed.wavelen, diskSed.wavelen)
            numpy.testing.assert_almost_equal(bulgeSed.wavelen, agnSed.wavelen)

            fl = bulgeSed.flambda + diskSed.flambda + agnSed.flambda

            totalSed = Sed(wavelen=bulgeSed.wavelen, flambda=fl)

            sedList = [totalSed, bulgeSed, diskSed, agnSed]

            for i, spectrum in enumerate(sedList):
                if i==0:
                    msgroot = 'failed on total'
                elif i==1:
                    msgroot = 'failed on bulge'
                elif i==2:
                    msgroot = 'failed on disk'
                elif i==3:
                    msgroot = 'failed on agn'

                for j, b in enumerate(self.bandpasses):
                    controlSigma = calcMagError_sed(spectrum, self.totalBandpasses[j],
                                             self.skySeds[j],
                                             self.hardwareBandpasses[j],
                                             FWHMeff=lsstDefaults.FWHMeff(b),
                                             photParams=PhotometricParameters())

                    testSigma = line[26+(i*6)+j]
                    msg = '%e neq %e; ' % (testSigma, controlSigma) + msgroot
                    self.assertAlmostEqual(testSigma, controlSigma, 10, msg=msg)
                    ct += 1

        self.assertGreater(ct, 0)
    def _calculateGalSimSeds(self):
        """
        Apply any physical corrections to the objects' SEDS (redshift them, apply dust, etc.).
        Return a list of Sed objects containing the SEDS
        """

        sedList = []
        actualSEDnames = self.column_by_name('sedFilepath')
        redshift = self.column_by_name('redshift')
        internalAv = self.column_by_name('internalAv')
        internalRv = self.column_by_name('internalRv')
        galacticAv = self.column_by_name('galacticAv')
        galacticRv = self.column_by_name('galacticRv')
        magNorm = self.column_by_name('magNorm')

        #for setting magNorm
        imsimband = Bandpass()
        imsimband.imsimBandpass()

        outputNames=[]

        for (sedName, zz, iAv, iRv, gAv, gRv, norm) in \
            zip(actualSEDnames, redshift, internalAv, internalRv, galacticAv, galacticRv, magNorm):

            if is_null(sedName):
                sedList.append(None)
            else:
                if sedName in self.uniqueSeds:
                    #we have already read in this file; no need to do it again
                    sed = Sed(wavelen=self.uniqueSeds[sedName].wavelen,
                              flambda=self.uniqueSeds[sedName].flambda,
                              fnu=self.uniqueSeds[sedName].fnu,
                              name=self.uniqueSeds[sedName].name)
                else:
                    #load the SED of the object
                    sed = Sed()
                    sedFile = os.path.join(self.sedDir, sedName)
                    sed.readSED_flambda(sedFile)

                    flambdaCopy = copy.deepcopy(sed.flambda)

                    #If the SED is zero inside of the bandpass, GalSim raises an error.
                    #This sets a minimum flux value of 1.0e-30 so that the SED is never technically
                    #zero inside of the bandpass.
                    sed.flambda = numpy.array([ff if ff>1.0e-30 else 1.0e-30 for ff in flambdaCopy])
                    sed.fnu = None

                    #copy the unnormalized file to uniqueSeds so we don't have to read it in again
                    sedCopy = Sed(wavelen=sed.wavelen, flambda=sed.flambda,
                                  fnu=sed.fnu, name=sed.name)
                    self.uniqueSeds[sedName] = sedCopy

                #normalize the SED
                #Consulting the file sed.py in GalSim/galsim/ it appears that GalSim expects
                #its SEDs to ultimately be in units of ergs/nm so that, when called, they can
                #be converted to photons/nm (see the function __call__() and the assignment of
                #self._rest_photons in the __init__() of galsim's sed.py file).  Thus, we need
                #to read in our SEDs, normalize them, and then multiply by the exposure time
                #and the effective area to get from ergs/s/cm^2/nm to ergs/nm.
                #
                #The gain parameter should convert between photons and ADU (so: it is the
                #traditional definition of "gain" -- electrons per ADU -- multiplied by the
                #quantum efficiency of the detector).  Because we fold the quantum efficiency
                #of the detector into our total_[u,g,r,i,z,y].dat bandpass files
                #(see the readme in the THROUGHPUTS_DIR/baseline/), we only need to multiply
                #by the electrons per ADU gain.
                #
                #We will take these parameters from an instantiation of the PhotometricParameters
                #class (which can be reassigned by defining a daughter class of this class)
                #
                fNorm = sed.calcFluxNorm(norm, imsimband)
                sed.multiplyFluxNorm(fNorm)

                #apply dust extinction (internal)
                if iAv != 0.0 and iRv != 0.0:
                    a_int, b_int = sed.setupCCMab()
                    sed.addCCMDust(a_int, b_int, A_v=iAv, R_v=iRv)

                #22 June 2015
                #apply redshift; there is no need to apply the distance modulus from
                #sims/photUtils/CosmologyWrapper; magNorm takes that into account
                #however, magNorm does not take into account cosmological dimming
                if zz != 0.0:
                    sed.redshiftSED(zz, dimming=True)

                #apply dust extinction (galactic)
                a_int, b_int = sed.setupCCMab()
                sed.addCCMDust(a_int, b_int, A_v=gAv, R_v=gRv)
                sedList.append(sed)

        return sedList
    np.savetxt('magNorm_list_sn.txt', magNorm_array)
    np.savetxt('av_list_sn.txt', av_array)
    np.savetxt('rv_list_sn.txt', rv_array)

    test_bandpassDict = BandpassDict.loadTotalBandpassesFromFiles()
    imsimband = Bandpass()
    imsimband.imsimBandpass()

    mag_norm_glsne = []
    for i, idx in list(enumerate(keep_rows)):
        if i % 10000 == 0:
            print(i, idx)
        test_sed = Sed()
        test_sed.readSED_flambda(os.path.join(str(os.environ['SIMS_SED_LIBRARY_DIR']), sed_name_array[i]))
        fnorm = test_sed.calcFluxNorm(dc2_df_system['lensgal_mi'].iloc[idx], test_bandpassDict['i'])
        test_sed.multiplyFluxNorm(fnorm)
        magNorm_diff = magNorm_array[3, i] - test_sed.calcMag(imsimband)
        mag_norm_glsne.append(magNorm_array[:,i] - magNorm_diff)

    mag_norm_glsne = np.array(mag_norm_glsne)

    results_dict = {}
    print(len(keep_rows), len(gcr_glsn_match[:, 0]))
    for keep_idx in range(len(keep_rows)):
        results_dict[str(dc2_df_system['sysno'].iloc[keep_rows[keep_idx]])] = {'z':gcr_glsn_match[:, 0][keep_idx],
                                                                               'sed_name':sed_name_array[keep_idx],
                                                                               'magNorm':mag_norm_glsne[keep_idx],
                                                                               'lens_av':av_array[keep_idx],
                                                                               'lens_rv':rv_array[keep_idx]}
    keep_systems = dc2_df_system['sysno'].iloc[keep_rows].values
Пример #57
0
def calc_adu(mag, bandpass):
    sed = Sed()
    sed.setFlatSED()
    fluxNorm = sed.calcFluxNorm(mag, bandpass)
    sed.multiplyFluxNorm(fluxNorm)
    return sed.calcADU(bandpass, fake_phot_params())
Пример #58
0
def calcM5s(hardware, system, atmos, title='m5'):
    photParams = PhotometricParameters()
    lsstDefaults = LSSTdefaults()
    darksky = Sed()
    darksky.readSED_flambda(os.path.join(os.getenv('SYSENG_THROUGHPUTS_DIR'), 'siteProperties', 'darksky.dat'))
    flatSed = Sed()
    flatSed.setFlatSED()
    m5 = {}
    sourceCounts = {}
    skyCounts = {}
    skyMag = {}
    gamma = {}
    for f in system:
        m5[f] = SignalToNoise.calcM5(darksky, system[f], hardware[f], photParams, seeing=lsstDefaults.seeing(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)
    print title
    print 'Filter m5 SourceCounts SkyCounts SkyMag Gamma'
    for f in ('u', 'g' ,'r', 'i', 'z', 'y'):
        print '%s %.2f %.1f %.2f %.2f %.6f' %(f, m5[f], sourceCounts[f], skyCounts[f], skyMag[f], gamma[f])

    # Show what these look like individually (add sky & m5 limits on throughput curves)
    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, 10)
    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.2')
    # Add legend for dark sky.
    myline = mlines.Line2D([], [], color='k', linestyle='-', label='Dark sky AB mags')
    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')
    if title == 'Vendor combo':
        title = ''
    plt.title('System total response curves %s' %(title))
    if title == '':
        plt.savefig('throughputs.pdf', format='pdf', dpi=600)
    return m5
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
Пример #60
0
    def loadSedsFromList(self, sedNameList, magNormList, \
                         internalAvList=None, galacticAvList=None, redshiftList=None):
        """
        Load the Seds specified by sedNameList, applying the specified normalization,
        extinction, and redshift.

        @param [in] sedList is a list of file names containing Seds

        @param [in] magNorm is the magnitude normalization

        @param [in] internalAvList is an optional list of A(V) due to internal
        dust

        @param [in] galacticAvList is an optional list of A(V) due to
        Milky Way dust

        @param [in] redshiftList is an optional list of redshifts for the
        input Sed

        Seds are read in and stored to this object's internal list of Seds.

        Note: if you constructed this SedList object without internalAvList,
        you cannot load Seds with internalAvList now.  Likewise for galacticAvlist
        and redshiftList.
        """

        if not self._initialized:
            if internalAvList is not None:
                self._internal_av_list = copy.deepcopy(list(internalAvList))
            else:
                self._internal_av_list = None

            if galacticAvList is not None:
                self._galactic_av_list = copy.deepcopy(list(galacticAvList))
            else:
                self._galactic_av_list = None

            if redshiftList is not None:
                self._redshift_list = copy.deepcopy(list(redshiftList))
            else:
                self._redshift_list = None

        else:
            if self._internal_av_list is None and internalAvList is not None:
                raise RuntimeError("This SedList does not contain internalAvList")
            elif self._internal_av_list is not None:
                if internalAvList is None:
                    self._internal_av_list += [None] * len(sedNameList)
                else:
                    self._internal_av_list += list(internalAvList)

            if self._galactic_av_list is None and galacticAvList is not None:
                raise RuntimeError("This SedList does not contain galacticAvList")
            elif self._galactic_av_list is not None:
                if galacticAvList is None:
                    self._galactic_av_list += [None] * len(sedNameList)
                else:
                    self._galactic_av_list += list(galacticAvList)

            if self._redshift_list is None and redshiftList is not None:
                raise RuntimeError("This SedList does not contain redshiftList")
            elif self._redshift_list is not None:
                if redshiftList is None:
                    self._redshift_list += [None] * len(sedNameList)
                else:
                    self._redshift_list += list(redshiftList)


        for sedName in sedNameList:

            if sedName not in self._unique_sed_dict:
                sed = Sed()
                if self._spec_map is not None:
                    sed.readSED_flambda(os.path.join(self._file_dir, self._spec_map[sedName]))
                else:
                    sed.readSED_flambda(os.path.join(self._file_dir, sedName))

                self._unique_sed_dict[sedName]=sed

        #now that we have loaded and copied all of the necessary SEDs,
        #we can apply magNorms
        temp_sed_list = []
        for sedName, magNorm in zip(sedNameList, magNormList):

            ss = self._unique_sed_dict[sedName]

            sed=Sed(wavelen=ss.wavelen,flambda=ss.flambda,fnu=ss.fnu, name=ss.name)

            if sedName != "None":
                fNorm = sed.calcFluxNorm(magNorm, self._normalizing_bandpass)
                sed.multiplyFluxNorm(fNorm)

            temp_sed_list.append(sed)


        if internalAvList is not None:
            self._av_int_wavelen, \
            self._a_int, \
            self._b_int = self.applyAv(temp_sed_list, internalAvList,
                                       self._av_int_wavelen, self._a_int, self._b_int)

        if redshiftList is not None:
            self.applyRedshift(temp_sed_list, redshiftList)

        if self._wavelen_match is not None:
            for sedObj in temp_sed_list:
                if sedObj.wavelen is not None:
                    sedObj.resampleSED(wavelen_match=self._wavelen_match)

        if galacticAvList is not None:
            self._av_gal_wavelen, \
            self._a_gal, \
            self._b_gal = self.applyAv(temp_sed_list, galacticAvList,
                                       self._av_gal_wavelen, self._a_gal, self._b_gal)

        self._sed_list += temp_sed_list

        self._initialized = True