示例#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 __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
示例#3
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
示例#4
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
示例#5
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
示例#6
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
示例#8
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
示例#9
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
示例#10
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
    def testApplication(self):
        """
        Test that PhotometricParameters get properly propagated into
        Sed methods.  We will test this using Sed.calcADU, since the ADU
        scale linearly with the appropriate parameter.
        """

        testSed = Sed()
        testSed.setFlatSED()

        testBandpass = Bandpass()
        testBandpass.readThroughput(os.path.join(lsst.utils.getPackageDir('throughputs'),
                                                 'baseline', 'total_g.dat'))

        control = testSed.calcADU(testBandpass,
                                  photParams=PhotometricParameters())

        testCase = PhotometricParameters(exptime=30.0)

        test = testSed.calcADU(testBandpass, photParams=testCase)

        self.assertGreater(control, 0.0)
        self.assertEqual(control, 0.5*test)
示例#12
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
示例#13
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 testApplication(self):
        """
        Test that PhotometricParameters get properly propagated into
        Sed methods.  We will test this using Sed.calcADU, since the ADU
        scale linearly with the appropriate parameter.
        """

        testSed = Sed()
        testSed.setFlatSED()

        testBandpass = Bandpass()
        testBandpass.readThroughput(
            os.path.join(lsst.utils.getPackageDir('throughputs'), 'baseline',
                         'total_g.dat'))

        control = testSed.calcADU(testBandpass,
                                  photParams=PhotometricParameters())

        testCase = PhotometricParameters(exptime=30.0)

        test = testSed.calcADU(testBandpass, photParams=testCase)

        self.assertTrue(control > 0.0)
        self.assertEqual(control, 0.5 * test)
示例#15
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
示例#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_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
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
示例#19
0
    def Simulate_LC_last(self):

        
        sed_SN=self.SN.get_SED(self.obs['mjd'])
        
        #print 'SED loaded'
        for i in range(len(sed_SN.wavelen)):
            obs=self.obs[i]
            sed=Sed(wavelen=sed_SN.wavelen[i],flambda=sed_SN.flambda[i])
            visittime=obs['exptime']
            filtre=obs['band'][-1]
            photParams = PhotometricParameters(nexp=visittime/15.)
            e_per_sec = sed.calcADU(bandpass=self.transmission.lsst_atmos_aerosol[filtre], photParams=photParams) #number of ADU counts for expTime
            e_per_sec/=visittime/photParams.gain

            flux_SN=sed.calcFlux(bandpass=self.transmission.lsst_atmos_aerosol[filtre])

            FWHMeff=obs['FWHMeff']
            if flux_SN >0:
                 
                mag_SN=-2.5 * np.log10(flux_SN / 3631.0)
                m5_calc,snr_m5_through=self.Get_m5(filtre,mag_SN,obs['sky'],photParams,FWHMeff)
                
                self.table_LC.add_row(('LSST::'+filtre,obs['mjd'],visittime,FWHMeff,obs['moon_frac'],obs['sky'],obs['kAtm'],obs['airmass'],obs['m5sigmadepth'],obs['Nexp'],e_per_sec,e_per_sec/snr_m5_through))
示例#20
0
    def get(self, what, band):
        """
        Decorator to access quantities

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

        """
        filter_trans = self.system[band]
        wavelen_min, wavelen_max, wavelen_step = filter_trans.getWavelenLimits(
            None, None, None)

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

        flatSedb = Sed()
        flatSedb.setFlatSED(wavelen_min, wavelen_max, wavelen_step)
        flux0b = np.power(10., -0.4 * self.mag_sky(band))
        flatSedb.multiplyFluxNorm(flux0b)
        photParams = PhotometricParameters(bandpass=band)
        norm = photParams.platescale**2 / 2. * photParams.exptime / photParams.gain
        trans = filter_trans

        if self.atmos:
            trans = self.atmosphere[band]
        self.data['m5'][band] = SignalToNoise.calcM5(
            flatSedb,
            trans,
            filter_trans,
            photParams=photParams,
            FWHMeff=self.FWHMeff(band))
        adu_int = flatSedb.calcADU(bandpass=trans, photParams=photParams)
        self.data['flux_sky'][band] = adu_int * norm
示例#21
0
 def testSedMagErrors(self):
     """Test error handling at mag and adu calculation levels of sed."""
     sedwavelen = np.arange(self.wmin+50, self.wmax, 1)
     sedflambda = np.ones(len(sedwavelen))
     testsed = Sed(wavelen=sedwavelen, flambda=sedflambda)
     # Test handling in calcMag
     with warnings.catch_warnings(record=True) as w:
         mag = testsed.calcMag(self.testbandpass)
         self.assertEqual(len(w), 1)
         self.assertIn("non-overlap", str(w[-1].message))
     np.testing.assert_equal(mag, np.NaN)
     # Test handling in calcADU
     with warnings.catch_warnings(record=True) as w:
         adu = testsed.calcADU(self.testbandpass,
                               photParams=PhotometricParameters())
         self.assertEqual(len(w), 1)
         self.assertIn("non-overlap", str(w[-1].message))
     np.testing.assert_equal(adu, np.NaN)
     # Test handling in calcFlux
     with warnings.catch_warnings(record=True) as w:
         flux = testsed.calcFlux(self.testbandpass)
         self.assertEqual(len(w), 1)
         self.assertIn("non-overlap", str(w[-1].message))
     np.testing.assert_equal(flux, np.NaN)
示例#22
0
 def testSedMagErrors(self):
     """Test error handling at mag and adu calculation levels of sed."""
     sedwavelen = np.arange(self.wmin + 50, self.wmax, 1)
     sedflambda = np.ones(len(sedwavelen))
     testsed = Sed(wavelen=sedwavelen, flambda=sedflambda)
     # Test handling in calcMag
     with warnings.catch_warnings(record=True) as w:
         mag = testsed.calcMag(self.testbandpass)
         self.assertEqual(len(w), 1)
         self.assertIn("non-overlap", str(w[-1].message))
     np.testing.assert_equal(mag, np.NaN)
     # Test handling in calcADU
     with warnings.catch_warnings(record=True) as w:
         adu = testsed.calcADU(self.testbandpass,
                               photParams=PhotometricParameters())
         self.assertEqual(len(w), 1)
         self.assertIn("non-overlap", str(w[-1].message))
     np.testing.assert_equal(adu, np.NaN)
     # Test handling in calcFlux
     with warnings.catch_warnings(record=True) as w:
         flux = testsed.calcFlux(self.testbandpass)
         self.assertEqual(len(w), 1)
         self.assertIn("non-overlap", str(w[-1].message))
     np.testing.assert_equal(flux, np.NaN)
示例#23
0
                            np_sed['flambda'])
        phys_params = PhysicalParameters()
        phot = flambda * np_filter['wav_nm'] / (phys_params.planck *
                                                phys_params.lightspeed * 1.0e9)

        integral = 0.5 * (
            (phot[1:] * np_filter['throughput'][1:] +
             phot[:-1] * np_filter['throughput'][:-1]) *
            (np_filter['wav_nm'][1:] - np_filter['wav_nm'][:-1])).sum()

        effarea = np.pi * (6.423 * 100.0 / 2.0)**2
        exptime = 30.0
        nexp = 1.0

        integral *= effarea * exptime * nexp

        # print results
        print('\n%s' % bp_name)
        print('catsim_counts (by hand) %e' % integral)

        if _LSST_STACK_INSTALLED:
            adu = spec.calcADU(bp, phot_params)
            print('catsim_counts (with sims_photUtils) %e' %
                  (adu * phot_params.gain))
            if bp_name != 'y':
                assert np.abs(adu * phot_params.gain -
                              integral) < 0.01 * integral

        print('phosim_counts %e' % phosim_truth)
        print('catsim_counts/phosim_counts %e' % (integral / phosim_truth))
示例#24
0
    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 = tempfile.mkdtemp(dir=ROOT, prefix='testObjectPlacement-')
        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 = 3
        rng = np.random.RandomState(42)
        pointingRaList = rng.random_sample(nSamples)*360.0
        pointingDecList = rng.random_sample(nSamples)*180.0 - 90.0
        rotSkyPosList = rng.random_sample(nSamples)*360.0
        fwhmList = rng.random_sample(nSamples)*1.0 + 0.3

        actualCounts = None

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

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

            xDisplacementList = rng.random_sample(nSamples)*60.0-30.0
            yDisplacementList = rng.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)
            cat.camera_wrapper = GalSimCameraWrapper(camera)
            if actualCounts is None:
                actualCounts = controlSed.calcADU(uBandpass, cat.photParams)

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

            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(np.radians(np.float(words[2])))
                        objDecList.append(np.radians(np.float(words[3])))

            objRaList = np.array(objRaList)
            objDecList = np.array(objDecList)

            self.assertGreater(len(objRaList), 0)  # make sure we aren't testing
                                                   # an empty catalog/image

            self.check_placement(imageName, objRaList, objDecList,
                                 [fwhm]*len(objRaList),
                                 np.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)

        if os.path.exists(scratchDir):
            shutil.rmtree(scratchDir)
from lsst.sims.photUtils import PhotometricParameters, Bandpass
phot_params = PhotometricParameters(nexp=1, exptime=30.0, gain=1)
imsim = Bandpass()
imsim.imsimBandpass()

target=20000.0
for name in galaxy_sed_list:
    magnorm_interp[name] = {}
    magnorm_interp[name]['z'] = np.arange(0.0, 2.4, 0.2)
    magnorm_interp[name]['mag'] = np.zeros(len(magnorm_interp[name]['z']), dtype=float)
    for i_zz, zz in enumerate(magnorm_interp[name]['z']):
        ss = Sed()
        ss.readSED_flambda(os.path.join(galaxy_dir, name))
        mag = ss.calcMag(imsim)
        ss.redshiftSED(zz, dimming=True)
        cts = ss.calcADU(bp_dict['r'], photParams=phot_params)
        magnorm = mag -2.5*np.log10(target/cts)

        ss = Sed()
        ss.readSED_flambda(os.path.join(galaxy_dir, name))
        fnorm = ss.calcFluxNorm(magnorm, imsim)
        ss.multiplyFluxNorm(fnorm)
        ss.redshiftSED(zz, dimming=True)
        new_cts = ss.calcADU(bp_dict['r'], photParams=phot_params)
        d_ct = np.abs(new_cts-target)
        
        magnorm_interp[name]['mag'][i_zz] = magnorm
        
        if d_ct>500.0:
            raise RuntimeWarning('d_ct %e' % d_ct)
# 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()
# You can use addCCMDust on the 'star' object itself, but I'm illustrating here how you could also
#  do otherwise - preserve the original 'star' object as is, and create a new Sed object that does
#  include the effects of dust ('dustystar').  Star's data will be unchanged by the dust. 
dustywavelen, dustyflambda = star.addCCMDust(a, b, ebv=ebv, wavelen=star.wavelen, flambda=star.flambda)
dustystar = Sed(wavelen=dustywavelen, flambda=dustyflambda)
magdust = dustystar.calcMag(rband)
print "With this dust, the magnitude of the star in this bandpass is now %.4f." %(magdust)
示例#27
0
def calcM5(hardware, system, atmos, title='m5', X=1.0, return_t2_values=False):
    """
    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
    effarea = np.pi * (6.423/2.*100.)**2
    photParams_zp = PhotometricParameters(exptime=1, nexp=1, gain=1, effarea=effarea,
                                          readnoise=8.8, othernoise=0, darkcurrent=0.2)
    photParams = PhotometricParameters(gain=1.0, effarea=effarea, readnoise=8.8, othernoise=0, darkcurrent=0.2)
    photParams_infinity = PhotometricParameters(gain=1.0, readnoise=0, darkcurrent=0,
                                                othernoise=0, effarea=effarea)
    # 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(getPackageDir('syseng_throughputs'),
                                         'siteProperties', 'darksky.dat'))
    flatSed = Sed()
    flatSed.setFlatSED()
    m5 = {}
    Tb = {}
    Sb = {}
    kAtm = {}
    Cm = {}
    dCm_infinity = {}
    sourceCounts = {}
    skyCounts = {}
    skyMag = {}
    gamma = {}
    zpT = {}
    FWHMgeom = {}
    FWHMeff = {}
    for f in system:
        zpT[f] = system[f].calcZP_t(photParams_zp)
        eff_wavelen = system[f].calcEffWavelen()[1]
        FWHMeff[f] = scale_seeing(0.62, eff_wavelen, X)[0]
        m5[f] = SignalToNoise.calcM5(darksky, system[f], hardware[f], photParams, FWHMeff=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)
        # Assumes atmosphere used in system throughput is X=1.0
        Cm[f] = (m5[f] - 0.5*(skyMag[f] - 21) - 2.5*np.log10(0.7/FWHMeff[f])
                 - 1.25*np.log10((photParams.exptime*photParams.nexp)/30.0) + kAtm[f]*(X-1.0))
        # Calculate Cm_Infinity by setting readout noise to zero.
        m5inf = SignalToNoise.calcM5(darksky, system[f], hardware[f],  photParams_infinity,
                                     FWHMeff=FWHMeff[f])
        Cm_infinity = (m5inf - 0.5*(skyMag[f] - 21) - 2.5*np.log10(0.7/FWHMeff[f])
                       - 1.25*np.log10((photParams.exptime*photParams.nexp)/30.0) + kAtm[f]*(X-1.0))
        dCm_infinity[f] = Cm_infinity - Cm[f]
    print('Filter FWHMeff FWHMgeom SkyMag SkyCounts Zp_t Tb Sb kAtm Gamma Cm dCm_infinity m5 SourceCounts')
    for f in ('u', 'g' ,'r', 'i', 'z', 'y'):
        FWHMgeom[f] = SignalToNoise.FWHMeff2FWHMgeom(FWHMeff[f])
        print('%s %.2f %.2f %.2f %.1f %.2f %.3f %.3f %.4f %.6f %.2f %.2f %.2f %.2f'\
           % (f, FWHMeff[f], FWHMgeom[f],
              skyMag[f], skyCounts[f], zpT[f], Tb[f], Sb[f], kAtm[f],
              gamma[f], Cm[f], dCm_infinity[f], m5[f], sourceCounts[f]))

    for f in filterlist:
        m5_cm = Cm[f] + 0.5*(skyMag[f] - 21.0) + 2.5*np.log10(0.7/FWHMeff[f]) - kAtm[f]*(X-1.0)
        if m5_cm - m5[f] > 0.001:
            raise ValueError('Cm calculation for %s band is incorrect! m5_cm != m5_snr' %f)

    if return_t2_values:
        return {'FWHMeff': FWHMeff, 'FWHMgeom': FWHMgeom, 'skyMag': skyMag, 'skycounts': skyCounts,
                'zpT': zpT, 'Tb': Tb, 'Sb': Sb, 'kAtm': kAtm,
                'gamma': gamma, 'Cm': Cm, 'dCm_infinity': dCm_infinity,
                'm5': m5, 'sourceCounts': sourceCounts}

    # 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(atmos.wavelen, atmos.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.savefig('../plots/throughputs.png', format='png')

    plt.figure()
    ax = plt.gca()
    # Add dark sky
    ax2 = ax.twinx()
    plt.sca(ax2)
    skyab = np.zeros(len(darksky.fnu))
    condition = np.where(darksky.fnu > 0)
    skyab[condition] = -2.5*np.log10(darksky.fnu[condition]) - 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))
    plt.savefig('../plots/system+sky' + title + '.png', format='png', dpi=600)
    return m5
示例#28
0
class Telescope(Throughputs):
    def __init__(self,
                 airmass=1,
                 atmos=True,
                 aerosol=False,
                 libradtran=False,
                 **kwargs):
        Throughputs.__init__(self, **kwargs)
        print("**** Telescope.__init__******")
        #self.filters=filterlist

        params = [
            'mag_sky', 'm5', 'FWHMeff', 'Tb', 'Sigmab', 'zp', 'counts_zp',
            'Skyb', 'flux_sky'
        ]

        self.data = {}
        for par in params:
            self.data[par] = {}

        self.data['FWHMeff'] = dict(
            zip('ugrizy', [0.92, 0.87, 0.83, 0.80, 0.78, 0.76]))

        self.atmos = atmos
        self.libradtran = libradtran

        self.Load_Atmosphere(airmass)
        self.sed = None
        self.sedAB0 = None

        self.Inputs()
        self.Sky()
        self.ZP()
        self.Set_SED_AB0()  # set a AB reference source

    #-------------------------------------------------------------------------
    @property
    def FWHMeff(self):
        return self.data['FWHMeff']

    #-------------------------------------------------------------------------
    @property
    def mag_sky(self):
        return self.data['mag_sky']

    #-------------------------------------------------------------------------
    @property
    def m5(self):
        return self.data['m5']

    #-------------------------------------------------------------------------
    @property
    def Tb(self):
        return self.data['Tb']

    #-------------------------------------------------------------------------
    @property
    def Sigmab(self):
        return self.data['Sigmab']

    #-------------------------------------------------------------------------
    @property
    def zp(self):
        return self.data['zp']

    #-------------------------------------------------------------------------
    @property
    def ADU_zp(self):
        return self.data['counts_zp']

    #-------------------------------------------------------------------------
    @property
    def flux_sky(self):
        return self.data['flux_sky']

    #-------------------------------------------------------------------------
    def Inputs(self):

        for filtre in self.filterlist:
            myup = self.Calc_Integ_Sed(self.darksky, self.system[filtre])
            self.data['Tb'][filtre] = self.Calc_Integ(self.atmosphere[filtre])
            self.data['Sigmab'][filtre] = self.Calc_Integ(self.system[filtre])
            self.data['mag_sky'][filtre] = -2.5 * np.log10(
                myup / (3631. * self.Sigmab[filtre]))

    #-------------------------------------------------------------------------
    def Sky(self):

        for filtre in self.filterlist:
            self.Calc_m5(filtre)

    #-------------------------------------------------------------------------
    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

    #-------------------------------------------------------------------------
    def ZP(self):

        for filtre in self.filterlist:
            self.ZP_filtre(filtre)
        #print 'zeropoints',self.data['zp'],self.data['counts_zp']
        #self.data['zp']=dict(zip(['u','g','r','i','z','y'],[27.03,28.53,28.27,27.91,27.49,26.78]))

    #-------------------------------------------------------------------------
    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

    #-------------------------------------------------------------------------
    def Calc_Integ(self, bandpass):
        """
        Calc_Integ():
        Compute sum  F(lambda).dlambda/lambda in band (no unit)
             - F(lamba) : pass band
             - lambda   : wavelength
             
             
        Tool function implemented by Phillie Gris (IN2P3)
          
        """
        resu = 0.
        dlam = 0
        for i, wave in enumerate(bandpass.wavelen):
            if i < len(bandpass.wavelen) - 1:
                dlam = bandpass.wavelen[i + 1] - wave
                resu += dlam * bandpass.sb[i] / wave
            #resu+=dlam*bandpass.sb[i]

        return resu

    #-------------------------------------------------------------------------
    def Calc_Integ_Sed(self, sed, bandpass, wavelen=None, fnu=None):
        """
        Calc_Integ_Sed(self,sed,bandpass,wavelen=None, fnu=None)
        
        Compute sum of  S_nu*F(lambda).dlambda/lambda in band units in erg/cm2/s/Hz
             - S_nu     : SED in erg/cm2/s/Hz
             - F(lamba) : pass band
             - lambda   : wavelength
             - force to use the SED S_nu (erg/cm2/s/Hz) instead of S_lamba (erg/cm2/s/nm)
             
        Tool function implemented by Phillie Gris (IN2P3)
        """

        use_self = sed._checkUseSelf(wavelen, fnu)
        # Use self values if desired, otherwise use values passed to function.
        if use_self:
            # Calculate fnu if required.
            if sed.fnu is None:
                # If fnu not present, calculate. (does not regrid).
                sed.flambdaTofnu()
            wavelen = sed.wavelen
            fnu = sed.fnu
        # Make sure wavelen/fnu are on the same wavelength grid as bandpass.

        wavelen, fnu = sed.resampleSED(wavelen,
                                       fnu,
                                       wavelen_match=bandpass.wavelen)
        fnu = np.nan_to_num(
            fnu)  # SDC(29/06/18) reset to 0 out of band where there are nan

        # Calculate the number of photons.
        nphoton = (fnu / wavelen * bandpass.sb).sum()
        dlambda = wavelen[1] - wavelen[0]

        return nphoton * dlambda

    #---------------------------------------------------------------
    def CalcMyMagnitudes(self):
        """
        CalcMyMagnitudes(sed)
        
        - author : Sylvie Dagoret-Campagne
        - affiliation : LAL/IN2P3/CNRS/FRANCE
        - date   : July 4th 2018
        
        Check how LSST Sim compute the magnitudes.
        Compute here with self.Calc_Integ_Sed() and Sed.calcMag()
        Used just for debug purpose
        
        """
        all_mag1 = []
        all_mag2 = []
        #sed.flambdaTofnu()

        for i, band in enumerate(self.filterlist):
            filter = self.lsst_atmos[band]
            #phinorm=filter.sbTophi()
            # resample the wavelength each time for the filter
            wl, fnu = self.sed.getSED_fnu()
            wavelen, fnu = self.sed.resampleSED(wl,
                                                fnu,
                                                wavelen_match=filter.wavelen)
            fnu = np.nan_to_num(
                fnu
            )  # SDC(29/06/18) reset to 0 out of band where there are nan

            self.sed = Sed(wavelen=wavelen, fnu=fnu, name=self.sed.name)
            mag1 = self.sed.calcMag(bandpass=filter, wavelen=wavelen, fnu=fnu)
            mag2 = -2.5 * np.log10(self.Calc_Integ_Sed(self.sed, filter))
            all_mag1.append(mag1)
            all_mag2.append(mag2)
            print('CalcMyMagnitudes :: band = {}, mag1= {} , mag2= {}'.format(
                i, mag1, mag2))
        return np.array(all_mag1), np.array(all_mag2)

    #---------------------------------------------------------------
    def CalcMyZP(self):
        """
        CalcMyZP()
        
        - author : Sylvie Dagoret-Campagne
        - affiliation : LAL/IN2P3/CNRS/FRANCE
        - date   : July 5th 2018
        
        Calculate the Zero Points for all bands.
        
        This calculation should assume 1 second exposure and unit electronic gain
        """

        for i, band in enumerate(self.filterlist):
            #for filtre in self.filterlist:
            filtre = self.lsst_atmos[band]

            # parameters
            photParams = PhotometricParameters(bandpass=band)
            Diameter = 2. * np.sqrt(
                photParams.effarea * 1.e-4 / np.pi)  # diameter in meter
            exptime = 2 * photParams.exptime
            gain = photParams.gain

            # lsst sim calculation
            # by definition Zero point is defined for unit gain and unit exposure
            zp1 = filtre.calcZP_t(photParams) + 2.5 * np.log10(gain / exptime)

            # my calculation : Zero point should be calculated for unit gain and per second of exposure

            # in Jansky divided by J (photon energy E=hc/lambda)
            Snu_Tl_dldivl_AB0 = self.Calc_Integ_Sed(self.sedAB0, filtre)

            # in photoelectron per meter squared per meters per second
            # h is the Planck constant h=6.626x 10^-34 J.s
            dN_PhEl_AB0 = Snu_Tl_dldivl_AB0 / h * 1e-26 * np.pi * Diameter**2 / 4.

            zp2 = +2.5 * np.log10(dN_PhEl_AB0)

            print(
                "CalcMyZP :: band = {}, zp1(lsst_sim) = {}, zp2(me)= {}, deltaZP= {}"
                .format(i, zp1, zp2, zp1 - zp2))

    #---------------------------------------------------------------
    def CalcMyPhElMagnitudes(self):
        """
        CalcMyElectronagnitudes(sed)
        
        - author : Sylvie Dagoret-Campagne
        - affiliation : LAL/IN2P3/CNRS/FRANCE
        - date   : July 5th 2018
        
        Calculate the instrumental magnitude (Photoelectrn unit) for all bands.
        
        """

        all_magPhEl = []

        for i, band in enumerate(self.filterlist):
            filter = self.lsst_atmos[band]

            #typical parameters of the band
            photParams = PhotometricParameters(bandpass=band)
            Diameter = 2. * np.sqrt(
                photParams.effarea * 1.e-4 / np.pi)  # diameter in meter
            exptime = 2 * photParams.exptime

            # resample the wavelength each time for the filter
            wl, fnu = self.sed.getSED_fnu()
            wavelen, fnu = self.sed.resampleSED(wl,
                                                fnu,
                                                wavelen_match=filter.wavelen)
            fnu = np.nan_to_num(
                fnu
            )  # SDC(29/06/18) reset to 0 out of band where there are nan

            #this SED_nu is now in Jansky, units of 10-23 erg/cm2/s/Hz
            # 1 erg=10-7 J
            # 1 cm^-2 = 10^4 m^-2
            # we have to multiply the SED_nu by 10-26 to be in J/m2/s/Hz
            self.sed = Sed(wavelen=wavelen, fnu=fnu, name=self.sed.name)

            # in Jansky divided by J (photon energy E=hc/lambda)
            Snu_Tl_dldivl = self.Calc_Integ_Sed(self.sed, filter)

            # in photoelectron per meter squared per meters per second
            # h is the Planck constant h=6.626x 10^-34 J.s
            dN_el = Snu_Tl_dldivl / h * 1e-26 * np.pi * Diameter**2 / 4. * exptime

            mag_el = -2.5 * np.log10(dN_el)
            print('CalcMyPhElMagnitudes :: band = {}, mag= {}'.format(
                i, mag_el))

            all_magPhEl.append(mag_el)

        return np.array(all_magPhEl)

    #---------------------------------------------------------------
    def CalcMyADUMagnitudes(self):
        """
        CalcMyADUMagnitudes(sed)
        
        - author : Sylvie Dagoret-Campagne
        - affiliation : LAL/IN2P3/CNRS/FRANCE
        - date   : July 5th 2018
        
        Calculate the instrumental magnitude (ADU unit) for all bands.
        
        
        """

        all_magADU = []

        for i, band in enumerate(self.filterlist):
            filter = self.lsst_atmos[band]

            #typical parameters of the band
            photParams = PhotometricParameters(bandpass=band)
            Diameter = 2. * np.sqrt(
                photParams.effarea * 1.e-4 / np.pi)  # diameter in meter
            exptime = 2 * photParams.exptime
            gain = photParams.gain

            # resample the wavelength each time for the filter
            wl, fnu = self.sed.getSED_fnu()
            wavelen, fnu = self.sed.resampleSED(wl,
                                                fnu,
                                                wavelen_match=filter.wavelen)
            fnu = np.nan_to_num(
                fnu
            )  # SDC(29/06/18) reset to 0 out of band where there are nan

            #this SED_nu is now in Jansky, units of 10-23 erg/cm2/s/Hz
            # 1 erg=10-7 J
            # 1 cm^-2 = 10^4 m^-2
            # we have to multiply the SED_nu by 10-26 to be in J/m2/s/Hz
            self.sed = Sed(wavelen=wavelen, fnu=fnu, name=self.sed.name)

            # in Jansky divided by J (photon energy E=hc/lambda)
            Snu_Tl_dldivl = self.Calc_Integ_Sed(self.sed, filter)

            # in photoelectron per meter squared per meters per second
            # h is the Planck constant h=6.626x 10^-34 J.s
            dN_ADU = Snu_Tl_dldivl / h * 1e-26 * np.pi * Diameter**2 / 4. * exptime / gain

            mag_ADU = -2.5 * np.log10(dN_ADU)
            mag_ADU2 = -2.5 * np.log10(
                self.sed.calcADU(bandpass=filter,
                                 photParams=photParams,
                                 wavelen=wavelen,
                                 fnu=fnu))

            print(
                'CalcMyADUMagnitudes :: band = {}, mag1= {}, mag2={}, deltaM={}'
                .format(i, mag_ADU, mag_ADU2, mag_ADU - mag_ADU2))

            all_magADU.append(mag_ADU)

        return np.array(all_magADU)

    #---------------------------------------------------------------
    def CalcMyADUMagnitude_filter(self, band):
        """
        CalcMyADUMagnitude_filter(band)
        
        - author : Sylvie Dagoret-Campagne
        - affiliation : LAL/IN2P3/CNRS/FRANCE
        - date   : July 5th 2018
        
        Calculate the instrumental magnitude (ADU unit) for one band.
        
        """

        filter = self.lsst_atmos[band]

        #typical parameters of the band
        photParams = PhotometricParameters(bandpass=band)
        Diameter = 2. * np.sqrt(
            photParams.effarea * 1.e-4 / np.pi)  # diameter in meter
        exptime = 2 * photParams.exptime
        gain = photParams.gain

        # resample the wavelength each time for the filter
        wl, fnu = self.sed.getSED_fnu()
        wavelen, fnu = self.sed.resampleSED(wl,
                                            fnu,
                                            wavelen_match=filter.wavelen)
        fnu = np.nan_to_num(
            fnu)  # SDC(29/06/18) reset to 0 out of band where there are nan

        #this SED_nu is now in Jansky, units of 10-23 erg/cm2/s/Hz
        # 1 erg=10-7 J
        # 1 cm^-2 = 10^4 m^-2
        # we have to multiply the SED_nu by 10-26 to be in J/m2/s/Hz
        self.sed = Sed(wavelen=wavelen, fnu=fnu, name=self.sed.name)

        # in Jansky divided by J (photon energy E=hc/lambda)
        Snu_Tl_dldivl = self.Calc_Integ_Sed(self.sed, filter)

        # in photoelectron per meter squared per meters per second
        # h is the Planck constant h=6.626x 10^-34 J.s
        dN_ADU = Snu_Tl_dldivl / h * 1e-26 * np.pi * Diameter**2 / 4. * exptime / gain

        mag_ADU = -2.5 * np.log10(dN_ADU)
        mag_ADU2 = -2.5 * np.log10(
            self.sed.calcADU(bandpass=filter,
                             photParams=photParams,
                             wavelen=wavelen,
                             fnu=fnu))

        #print('CalcMyADUMagnitude_filter :: band = {}, mag1(me)= {}, mag2(lsst_sim)={}, deltaM={}'.format(band,mag_ADU,mag_ADU2,mag_ADU-mag_ADU2))

        return mag_ADU

    #---------------------------------------------------------------------
    def CalcMyABMagnitudes(self):
        """
        CalcMyABMagnitudes()
        
        - author : Sylvie Dagoret-Campagne
        - affiliation : LAL/IN2P3/CNRS/FRANCE
        - date   : July 4th 2018
        
        Calculate the magnitude in AB system unit for all bands.
        """

        all_magAB = []

        for i, band in enumerate(self.filterlist):
            filter = self.lsst_atmos[band]

            # resample the wavelength each time for the filter
            wl, fnu = self.sed.getSED_fnu()
            wavelen, fnu = self.sed.resampleSED(wl,
                                                fnu,
                                                wavelen_match=filter.wavelen)
            fnu = np.nan_to_num(
                fnu
            )  # SDC(29/06/18) reset to 0 out of band where there are nan

            self.sed = Sed(wavelen=wavelen, fnu=fnu, name=self.sed.name)

            mag1 = -2.5 * np.log10(self.Calc_Integ_Sed(self.sed, filter))
            mag2 = -2.5 * np.log10(self.Calc_Integ_Sed(self.sedAB0, filter))
            all_magAB.append(mag1 - mag2)

            mag3 = self.sed.calcMag(bandpass=filter, wavelen=wavelen, fnu=fnu)

            print(
                'CalcMyABMagnitudes :: band = {}, mag1={} , mag2={} , deltaM(me)={}, mag3(lsst)={}'
                .format(i, mag1, mag2, mag1 - mag2, mag3))
        return np.array(all_magAB)

    #---------------------------------------------------------------------
    def CalcMyABMagnitude_filter(self, band):
        """
        CalcMyABMagnitudes_filter()
        
        - author : Sylvie Dagoret-Campagne
        - affiliation : LAL/IN2P3/CNRS/FRANCE
        - date   : July 4th 2018
        
        Calculate the magnitude in AB system unit for all bands.
        """

        filter = self.lsst_atmos[band]

        # resample the wavelength each time for the filter
        wl, fnu = self.sed.getSED_fnu()
        wavelen, fnu = self.sed.resampleSED(wl,
                                            fnu,
                                            wavelen_match=filter.wavelen)
        fnu = np.nan_to_num(
            fnu)  # SDC(29/06/18) reset to 0 out of band where there are nan

        self.sed = Sed(wavelen=wavelen, fnu=fnu, name=self.sed.name)

        mag1 = -2.5 * np.log10(self.Calc_Integ_Sed(self.sed, filter))
        mag2 = -2.5 * np.log10(self.Calc_Integ_Sed(self.sedAB0, filter))
        mag3 = self.sed.calcMag(bandpass=filter, wavelen=wavelen, fnu=fnu)

        #print('CalcMyABMagnitude_filter :: band = {}, mag1={} , mag2={} , deltaM(me)={}, mag3(lsst)={}'.format(band,mag1,mag2,mag1-mag2,mag3))
        return mag3

    #---------------------------------------------------------------
    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)

    #---------------------------------------------------------------
    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

    #---------------------------------------------------------------
    def Plot_Filter(self):
        plt.figure(figsize=(5, 4))
        for i, band in enumerate(self.filterlist):
            filter = self.lsst_atmos[band]
            #phinorm=filter.sbTophi()
            #print('phinorm',phinorm)
            plt.plot(filter.wavelen, filter.sb, 'k:')
            #plt.plot(filter.wavelen, phinorm, 'r.')
        plt.show()

    #-------------------------------------------------------------------------
    def flux_to_mag(self, flux, band, zp=None):
        if zp is None:
            zp = self.zero_points(band)
        print('Telescope::flux_to_mag: zp', zp, band)
        m = -2.5 * np.log10(flux) + zp
        return m

    #-------------------------------------------------------------------------
    def mag_to_flux(self, mag, band, zp=None):
        if zp is None:
            zp = self.zero_points(band)
        return np.power(10., -0.4 * (mag - zp))

    #-------------------------------------------------------------------------
    def zero_points(self, band):
        return np.asarray([self.zp[b] for b in band])

    #-------------------------------------------------------------------------
    def mag_to_flux_e_sec(self, mag, band, trans, sed):

        #this should be debugged at some point
        photrams = PhotometricParameters(bandpass=band)
        E_per_sec = sed.calcADU(bandpass=trans, photParams=photParams)
        e_per_sec /= exptime / photParams.gain
        return e_per_sec

    #-------------------------------------------------------------------------
    def Set_SEDAB(self):
        """
        Set AB source :
        Enter the SED in erg/cm2/s/nm,
        """

        M0 = 48.6  # magnitude of a AB source
        S_nu0 = 10**(-M0 / 2.5)  # flux in erg/cm2/s/Hz : 3.630780547701003e-20
        c = 2.99792458e10  # speed of light in cm/s in CGS
        nm_to_cm = 1e-7  # conversion nm to cm
        wavelength = np.arange(300., 1151., 1)
        S_lambda0 = S_nu0 * c / (nm_to_cm) / wavelength**2  # in erg/cm2/s/nm

        self.Set_SED(wavel=wavelength, newsed=S_lambda0, name='AB-source')

    #-------------------------------------------------------------------------
    def Set_SED_AB0(self):
        """
        Set AB source :
        Enter the SED in erg/cm2/s/nm,
        """

        M0 = 48.6  # magnitude of a AB source
        S_nu0 = 10**(-M0 / 2.5)  # flux in erg/cm2/s/Hz : 3.630780547701003e-20
        c = 2.99792458e10  # speed of light in cm/s in CGS
        nm_to_cm = 1e-7  # conversion nm to cm
        wavelength = np.arange(300., 1151., 1)
        S_lambda0 = S_nu0 * c / (nm_to_cm) / wavelength**2  # in erg/cm2/s/nm

        self.sedAB0 = Sed(wavelen=wavelength,
                          flambda=S_lambda0,
                          fnu=None,
                          name='AB0-source')
        self.sedAB0.flambdaTofnu()

    #-------------------------------------------------------------------------
    def Set_SED(self, wavel, newsed, name='Pickles'):
        """
        Set_SED(self,wavel,sed):
        Enter the SED in erg/cm2/s/nm,
        """

        self.sed = Sed(wavelen=wavel, flambda=newsed, fnu=None, name=name)
        self.sed.flambdaTofnu()

    #-------------------------------------------------------------------------
    def Plot_SED(self):
        wl, fnu = self.sed.getSED_fnu()
        plt.plot(wl, fnu, 'b-')
        plt.xlabel("$\lambda$ (nm)")
        plt.ylabel("Flux in Jansky ($10^{-23}erg/cm^2/s/Hz$")
        title = 'SED '
        plt.title(title)
        plt.grid(True)
示例#29
0
def calcM5(hardware, system, atmos, title='m5', return_t2_values=False):
    """
    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
    effarea = np.pi * (6.423/2.*100.)**2
    photParams_zp = PhotometricParameters(exptime=1, nexp=1, gain=1, effarea=effarea,
                                          readnoise=8.8, othernoise=0, darkcurrent=0.2)
    photParams = PhotometricParameters(gain=1.0, effarea=effarea, readnoise=8.8, othernoise=0, darkcurrent=0.2)
    photParams_infinity = PhotometricParameters(gain=1.0, readnoise=0, darkcurrent=0,
                                                othernoise=0, effarea=effarea)
    # 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(getPackageDir('syseng_throughputs'),
                                         'siteProperties', 'darksky.dat'))
    flatSed = Sed()
    flatSed.setFlatSED()
    m5 = {}
    Tb = {}
    Sb = {}
    kAtm = {}
    Cm = {}
    dCm_infinity = {}
    sourceCounts = {}
    skyCounts = {}
    skyMag = {}
    gamma = {}
    zpT = {}
    FWHMgeom = {}
    FWHMeff = {}
    for f in system:
        zpT[f] = system[f].calcZP_t(photParams_zp)
        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)
        # 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))
                 - 1.25*np.log10((photParams.exptime*photParams.nexp)/30.0) + kAtm[f]*(X-1.0))
        # 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))
                       - 1.25*np.log10((photParams.exptime*photParams.nexp)/30.0) + kAtm[f]*(X-1.0))
        dCm_infinity[f] = Cm_infinity - Cm[f]
    print 'Filter FWHMeff FWHMgeom SkyMag SkyCounts Zp_t Tb Sb kAtm Gamma Cm dCm_infinity m5 SourceCounts'
    for f in ('u', 'g' ,'r', 'i', 'z', 'y'):
        FWHMeff[f] = lsstDefaults.FWHMeff(f)
        FWHMgeom[f] = SignalToNoise.FWHMeff2FWHMgeom(lsstDefaults.FWHMeff(f))
        print '%s %.2f %.2f %.2f %.1f %.2f %.3f %.3f %.4f %.6f %.2f %.2f %.2f %.2f'\
           % (f, FWHMeff[f], FWHMgeom[f],
              skyMag[f], skyCounts[f], zpT[f], Tb[f], Sb[f], kAtm[f],
              gamma[f], Cm[f], dCm_infinity[f], m5[f], sourceCounts[f])
    if return_t2_values:
        return {'FHWMeff': FWHMeff, 'FWHMgeom': FWHMgeom, 'skyMag': skyMag, 'skycounts': skyCounts,
                'zpT': zpT, 'Tb': Tb, 'Sb': Sb, 'kAtm': kAtm,
                'gamma': gamma, 'Cm': Cm, 'dCm_infinity': dCm_infinity,
                'm5': m5, 'sourceCounts': sourceCounts}

    for f in filterlist:
        m5_cm = Cm[f] + 0.5*(skyMag[f] - 21.0) + 2.5*np.log10(0.7/lsstDefaults.FWHMeff(f))
        if m5_cm - m5[f] > 0.001:
            raise ValueError('Cm calculation for %s band is incorrect! m5_cm != m5_snr' %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.savefig('../plots/throughputs.png', format='png')

    plt.figure()
    ax = plt.gca()
    # Add dark sky
    ax2 = ax.twinx()
    plt.sca(ax2)
    skyab = np.zeros(len(darksky.fnu))
    condition = np.where(darksky.fnu > 0)
    skyab[condition] = -2.5*np.log10(darksky.fnu[condition]) - 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))
    plt.savefig('../plots/system+sky' + title + '.png', format='png', dpi=600)
    return m5
示例#30
0
                out_name = os.path.join(
                    out_dir,
                    'instcat_galaxy_grid_%.1f_%d.txt' % (redshift, i_filter))
                with open(out_name, 'w') as instcat_handle:
                    phosim_header['obshistid'] = i_filter * 100 + int(
                        redshift / 0.1) + 1

                    write_phoSim_header(obs, instcat_handle, phosim_header)
                    for ii, (rr, dd) in enumerate(zip(ra, dec)):
                        unqid = ii + 1
                        instcat_handle.write('object %d ' % unqid)
                        instcat_handle.write('%.17f %.17f %.6f ' %
                                             (rr, dd, magnorm))
                        instcat_handle.write('galaxySED/%s ' % sed_names[ii])
                        instcat_handle.write(
                            '%1.f 0 0 0 0 0 point none none\n' % redshift)
                        if i_filter == 0:
                            ss = Sed()
                            ss.readSED_flambda(
                                os.path.join(galaxy_dir, sed_names[ii]))
                            fnorm = ss.calcFluxNorm(magnorm, imsim)
                            ss.multiplyFluxNorm(fnorm)
                            ss.redshiftSED(redshift, dimming=True)
                            ref_handle.write('%d %.17f %.17f ' %
                                             (unqid, rr, dd))
                            for bp in bp_dict:
                                adu = ss.calcADU(bp_dict[bp],
                                                 photParams=phot_params)
                                ref_handle.write('%e ' % adu)
                            ref_handle.write('\n')
def process_instance_catalog(catalog_name, centroid_dir, bp_dict):

    sed_dir = getPackageDir('sims_sed_library')

    i_filter = -1
    obshistid = -1
    with open(catalog_name, 'r') as in_file:
        for line in in_file:
            params = line.strip().split()
            if params[0] == 'filter':
                i_filter = int(params[1])
            if params[0] == 'obshistid':
                obshistid = int(params[1])

            if i_filter >= 0 and obshistid >= 0:
                break

    filter_name = 'ugrizy'[i_filter]
    bp = bp_dict[filter_name]

    objid_arr = []
    flux_arr = []
    redshift_arr = []
    magnorm_arr = []
    phot_params = PhotometricParameters(nexp=1, exptime=30.0, gain=1.0)

    with open(catalog_name, 'r') as in_file:
        for line in in_file:
            params = line.strip().split()
            if params[0] != 'object':
                continue

            sed_name = params[5]
            obj_id = int(params[1])
            magnorm = float(params[4])
            redshift = float(params[6])
            spec = Sed()
            spec.readSED_flambda(os.path.join(sed_dir, sed_name))
            fnorm = getImsimFluxNorm(spec, magnorm)
            spec.multiplyFluxNorm(fnorm)
            spec.redshiftSED(redshift, dimming=True)
            adu = spec.calcADU(bp, photParams=phot_params)
            objid_arr.append(obj_id)
            flux_arr.append(adu)
            redshift_arr.append(redshift)
            magnorm_arr.append(magnorm)

    centroid_files = os.listdir(centroid_dir)
    phosim_objid_arr = []
    phosim_flux_arr = []
    x_arr = []
    y_arr = []
    chip_name_arr = []
    dtype = np.dtype([('id', int), ('phot', float), ('x', float),
                      ('y', float)])
    for file_name in centroid_files:
        if 'e_%d' % obshistid not in file_name or 'f%d' % i_filter not in file_name:
            continue
        name_params = file_name.split('_')
        raft = name_params[5]
        sensor = name_params[6]
        chip_name = '%s:%s,%s %s:%s,%s' % (raft[0], raft[1], raft[2],
                                           sensor[0], sensor[1], sensor[2])
        full_name = os.path.join(centroid_dir, file_name)
        data = np.genfromtxt(full_name, dtype=dtype, skip_header=1)
        for line in data:
            phosim_objid_arr.append(line['id'])
            phosim_flux_arr.append(line['phot'])
            x_arr.append(line['x'])
            y_arr.append(line['y'])
            chip_name_arr.append(chip_name)

    objid_arr = np.array(objid_arr)
    flux_arr = np.array(flux_arr)
    redshift_arr = np.array(redshift_arr)
    magnorm_arr = np.array(magnorm_arr)
    phosim_objid_arr = np.array(phosim_objid_arr)
    phosim_flux_arr = np.array(phosim_flux_arr)
    x_arr = np.array(x_arr)
    y_arr = np.array(y_arr)
    chip_name_arr = np.array(chip_name_arr)

    sorted_dex = np.argsort(objid_arr)
    objid_arr = objid_arr[sorted_dex]
    flux_arr = flux_arr[sorted_dex]
    redshift_arr = redshift_arr[sorted_dex]
    magnorm_arr = magnorm_arr[sorted_dex]

    sorted_dex = np.argsort(phosim_objid_arr)
    phosim_objid_arr = phosim_objid_arr[sorted_dex]
    phosim_flux_arr = phosim_flux_arr[sorted_dex]
    x_arr = x_arr[sorted_dex]
    y_arr = y_arr[sorted_dex]
    chip_name_arr = chip_name_arr[sorted_dex]

    np.testing.assert_array_equal(phosim_objid_arr, objid_arr)

    return (objid_arr, flux_arr, phosim_flux_arr, redshift_arr, magnorm_arr,
            x_arr, y_arr, chip_name_arr, filter_name)
示例#32
0
    def test_object_extraction_stars(self):
        """
        Test that method to get GalSimCelestialObjects from
        InstanceCatalogs works
        """
        commands = desc.imsim.metadata_from_file(self.phosim_file)
        obs_md = desc.imsim.phosim_obs_metadata(commands)
        phot_params = desc.imsim.photometricParameters(commands)
        with desc.imsim.fopen(self.phosim_file, mode='rt') as input_:
            lines = [x for x in input_ if x.startswith('object')]

        truth_dtype = np.dtype([('uniqueId', str, 200), ('x_pupil', float),
                                ('y_pupil', float), ('sedFilename', str, 200),
                                ('magNorm', float), ('raJ2000', float),
                                ('decJ2000', float), ('pmRA', float),
                                ('pmDec', float), ('parallax', float),
                                ('v_rad', float), ('Av', float),
                                ('Rv', float)])

        truth_data = np.genfromtxt(os.path.join(self.data_dir,
                                                'truth_stars.txt'),
                                   dtype=truth_dtype,
                                   delimiter=';')

        truth_data.sort()

        gs_object_arr, gs_object_dict \
            = sources_from_list(lines, obs_md, phot_params, self.phosim_file)

        id_arr = [None] * len(gs_object_arr)
        for i_obj in range(len(gs_object_arr)):
            id_arr[i_obj] = gs_object_arr[i_obj].uniqueId
        id_arr = sorted(id_arr)
        np.testing.assert_array_equal(truth_data['uniqueId'], id_arr)

        ######## test that pupil coordinates are correct to within
        ######## half a milliarcsecond

        x_pup_test, y_pup_test = _pupilCoordsFromRaDec(
            truth_data['raJ2000'],
            truth_data['decJ2000'],
            pm_ra=truth_data['pmRA'],
            pm_dec=truth_data['pmDec'],
            v_rad=truth_data['v_rad'],
            parallax=truth_data['parallax'],
            obs_metadata=obs_md)

        for gs_obj in gs_object_arr:
            i_obj = np.where(truth_data['uniqueId'] == gs_obj.uniqueId)[0][0]
            dd = np.sqrt((x_pup_test[i_obj] - gs_obj.xPupilRadians)**2 +
                         (y_pup_test[i_obj] - gs_obj.yPupilRadians)**2)
            dd = arcsecFromRadians(dd)
            self.assertLess(dd, 0.0005)

        ######## test that fluxes are correctly calculated

        bp_dict = BandpassDict.loadTotalBandpassesFromFiles()
        imsim_bp = Bandpass()
        imsim_bp.imsimBandpass()
        phot_params = PhotometricParameters(nexp=1, exptime=30.0)

        for gs_obj in gs_object_arr:
            i_obj = np.where(truth_data['uniqueId'] == gs_obj.uniqueId)[0][0]
            sed = Sed()
            full_sed_name = os.path.join(os.environ['SIMS_SED_LIBRARY_DIR'],
                                         truth_data['sedFilename'][i_obj])
            sed.readSED_flambda(full_sed_name)
            fnorm = sed.calcFluxNorm(truth_data['magNorm'][i_obj], imsim_bp)
            sed.multiplyFluxNorm(fnorm)
            sed.resampleSED(wavelen_match=bp_dict.wavelenMatch)
            a_x, b_x = sed.setupCCM_ab()
            sed.addDust(a_x,
                        b_x,
                        A_v=truth_data['Av'][i_obj],
                        R_v=truth_data['Rv'][i_obj])

            for bp in ('u', 'g', 'r', 'i', 'z', 'y'):
                flux = sed.calcADU(bp_dict[bp], phot_params) * phot_params.gain
                self.assertAlmostEqual(flux / gs_obj.flux(bp), 1.0, 10)

        ######## test that objects are assigned to the right chip in
        ######## gs_object_dict

        unique_id_dict = {}
        for chip_name in gs_object_dict:
            local_unique_id_list = []
            for gs_object in gs_object_dict[chip_name]:
                local_unique_id_list.append(gs_object.uniqueId)
            local_unique_id_list = set(local_unique_id_list)
            unique_id_dict[chip_name] = local_unique_id_list

        valid = 0
        valid_chip_names = set()
        for unq, xpup, ypup in zip(truth_data['uniqueId'],
                                   truth_data['x_pupil'],
                                   truth_data['y_pupil']):

            chip_name = chipNameFromPupilCoordsLSST(xpup, ypup)
            if chip_name is not None:
                self.assertIn(unq, unique_id_dict[chip_name])
                valid_chip_names.add(chip_name)
                valid += 1

        self.assertGreater(valid, 10)
        self.assertGreater(len(valid_chip_names), 5)
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
    effarea = np.pi * (6.423 / 2. * 100.)**2
    photParams_zp = PhotometricParameters(exptime=1,
                                          nexp=1,
                                          gain=1,
                                          effarea=effarea,
                                          readnoise=8.8,
                                          othernoise=0,
                                          darkcurrent=0.2)
    photParams = PhotometricParameters(gain=1.0,
                                       effarea=effarea,
                                       readnoise=8.8,
                                       othernoise=0,
                                       darkcurrent=0.2)
    photParams_infinity = PhotometricParameters(gain=1.0,
                                                readnoise=0,
                                                darkcurrent=0,
                                                othernoise=0,
                                                effarea=effarea)
    # 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
示例#34
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())
示例#35
0
    def test_object_extraction_galaxies(self):
        """
        Test that method to get GalSimCelestialObjects from
        InstanceCatalogs works
        """
        galaxy_phosim_file = os.path.join(self.data_dir, 'phosim_galaxies.txt')
        commands = desc.imsim.metadata_from_file(galaxy_phosim_file)
        obs_md = desc.imsim.phosim_obs_metadata(commands)
        phot_params = desc.imsim.photometricParameters(commands)
        (gs_object_arr, gs_object_dict) = desc.imsim.sources_from_file(
            galaxy_phosim_file, obs_md, phot_params)

        id_arr = np.zeros(len(gs_object_arr), dtype=int)
        for i_obj in range(len(gs_object_arr)):
            id_arr[i_obj] = gs_object_arr[i_obj].uniqueId

        truth_dtype = np.dtype([('uniqueId', int), ('x_pupil', float),
                                ('y_pupil', float), ('sedFilename', str, 200),
                                ('magNorm', float), ('raJ2000', float),
                                ('decJ2000', float), ('redshift', float),
                                ('gamma1', float), ('gamma2', float),
                                ('kappa', float), ('galacticAv', float),
                                ('galacticRv', float), ('internalAv', float),
                                ('internalRv', float), ('minorAxis', float),
                                ('majorAxis', float), ('positionAngle', float),
                                ('sindex', float)])

        truth_data = np.genfromtxt(os.path.join(self.data_dir,
                                                'truth_galaxies.txt'),
                                   dtype=truth_dtype,
                                   delimiter=';')

        np.testing.assert_array_equal(truth_data['uniqueId'], id_arr)

        ######## test that galaxy parameters are correctly read in

        g1 = truth_data['gamma1'] / (1.0 - truth_data['kappa'])
        g2 = truth_data['gamma2'] / (1.0 - truth_data['kappa'])
        mu = 1.0 / ((1.0 - truth_data['kappa'])**2 -
                    (truth_data['gamma1']**2 + truth_data['gamma2']**2))
        for i_obj, gs_obj in enumerate(gs_object_arr):
            self.assertAlmostEqual(gs_obj.mu / mu[i_obj], 1.0, 6)
            self.assertAlmostEqual(gs_obj.g1 / g1[i_obj], 1.0, 6)
            self.assertAlmostEqual(gs_obj.g2 / g2[i_obj], 1.0, 6)
            self.assertGreater(np.abs(gs_obj.mu), 0.0)
            self.assertGreater(np.abs(gs_obj.g1), 0.0)
            self.assertGreater(np.abs(gs_obj.g2), 0.0)

            self.assertAlmostEqual(gs_obj.halfLightRadiusRadians,
                                   truth_data['majorAxis'][i_obj], 13)
            self.assertAlmostEqual(gs_obj.minorAxisRadians,
                                   truth_data['minorAxis'][i_obj], 13)
            self.assertAlmostEqual(gs_obj.majorAxisRadians,
                                   truth_data['majorAxis'][i_obj], 13)
            self.assertAlmostEqual(gs_obj.positionAngleRadians,
                                   truth_data['positionAngle'][i_obj], 7)
            self.assertAlmostEqual(gs_obj.sindex, truth_data['sindex'][i_obj],
                                   10)

        ######## test that pupil coordinates are correct to within
        ######## half a milliarcsecond

        x_pup_test, y_pup_test = _pupilCoordsFromRaDec(truth_data['raJ2000'],
                                                       truth_data['decJ2000'],
                                                       obs_metadata=obs_md)

        for i_obj, gs_obj in enumerate(gs_object_arr):
            self.assertEqual(truth_data['uniqueId'][i_obj], gs_obj.uniqueId)
            dd = np.sqrt((x_pup_test[i_obj] - gs_obj.xPupilRadians)**2 +
                         (y_pup_test[i_obj] - gs_obj.yPupilRadians)**2)
            dd = arcsecFromRadians(dd)
            self.assertLess(dd, 0.0005)

        ######## test that fluxes are correctly calculated

        bp_dict = BandpassDict.loadTotalBandpassesFromFiles()
        imsim_bp = Bandpass()
        imsim_bp.imsimBandpass()
        phot_params = PhotometricParameters(nexp=1, exptime=30.0)

        for i_obj, gs_obj in enumerate(gs_object_arr):
            sed = Sed()
            full_sed_name = os.path.join(os.environ['SIMS_SED_LIBRARY_DIR'],
                                         truth_data['sedFilename'][i_obj])
            sed.readSED_flambda(full_sed_name)
            fnorm = sed.calcFluxNorm(truth_data['magNorm'][i_obj], imsim_bp)
            sed.multiplyFluxNorm(fnorm)

            a_x, b_x = sed.setupCCMab()
            sed.addCCMDust(a_x,
                           b_x,
                           A_v=truth_data['internalAv'][i_obj],
                           R_v=truth_data['internalRv'][i_obj])

            sed.redshiftSED(truth_data['redshift'][i_obj], dimming=True)
            sed.resampleSED(wavelen_match=bp_dict.wavelenMatch)
            a_x, b_x = sed.setupCCMab()
            sed.addCCMDust(a_x,
                           b_x,
                           A_v=truth_data['galacticAv'][i_obj],
                           R_v=truth_data['galacticRv'][i_obj])

            for bp in ('u', 'g', 'r', 'i', 'z', 'y'):
                flux = sed.calcADU(bp_dict[bp], phot_params) * phot_params.gain
                self.assertAlmostEqual(flux / gs_obj.flux(bp), 1.0, 6)

        ######## test that objects are assigned to the right chip in
        ######## gs_object_dict

        unique_id_dict = {}
        for chip_name in gs_object_dict:
            local_unique_id_list = []
            for gs_object in gs_object_dict[chip_name]:
                local_unique_id_list.append(gs_object.uniqueId)
            local_unique_id_list = set(local_unique_id_list)
            unique_id_dict[chip_name] = local_unique_id_list

        valid = 0
        valid_chip_names = set()
        for unq, xpup, ypup in zip(truth_data['uniqueId'],
                                   truth_data['x_pupil'],
                                   truth_data['y_pupil']):

            chip_name = chipNameFromPupilCoordsLSST(xpup, ypup)[0]
            if chip_name is not None:
                self.assertIn(unq, unique_id_dict[chip_name])
                valid_chip_names.add(chip_name)
                valid += 1

        self.assertGreater(valid, 10)
        self.assertGreater(len(valid_chip_names), 5)
def calcM5(hardware, system, atmos, title='m5'):
    effarea = np.pi * (6.423/2.0*100.)**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
示例#37
0
    def __init__(self,logobs,parameters,model,version):


        self.mjd_name='mjd'
        self.FWHMeff='seeing'
        peakAbsMagBesselB=-19.0906
        alpha=0.13
        beta=3.
        
        mycosmology=FlatLambdaCDM(H0=70, Om0=0.25)
        self.astropy_cosmo=FlatLambdaCDM(H0= mycosmology.H0, Om0=mycosmology.Om0)
        instrument = instruments.InstrumentModel("STANDARD")
        B = instrument.EffectiveFilterByBand("B")
        magsys = instruments.MagSys('VEGA')
        zp = magsys.ZeroPoint(B)

        print 'zeropoint for b-band',zp
        flux_at_10pc = np.power(10., -0.4 * (peakAbsMagBesselB-zp))
        fs = salt2.load_filters(['STANDARD::B'])
        mc = salt2.ModelComponents('salt2.npz')
        s = salt2.SALT2([0.], ['STANDARD::B'], mc, fs, z=0.)
        raw_model_norm = s()[0]
        # (10pc)^2 in kpc^2
        self.X0_norm = flux_at_10pc * 1.E-4 / raw_model_norm

        table_obs=ascii.read(logobs,fast_reader=False)

        colnames=[]
        sfile=open(logobs,'r')
        for line in sfile.readlines():
            if line.count('#'):
                colnames.append(line[1:].split(':')[0].strip())

        for i,val in enumerate(table_obs.colnames):
            #if val.count('#') >= 1:
            table_obs.rename_column(val, colnames[i])

        self.lc=[]

        print table_obs

        self.params=Table(names=('t0','c','x1','z','ra','dec','status','fit','sn_type','sn_model','sn_version','mbsim','x0','dL'),dtype=('f8','f8','f8','f8','f8','S8','S8','f8','S8','S8','S8','f8','f8','f8'))

        self.transmission=Throughputs()
       
        dust = sncosmo.OD94Dust()

        model=model
        version=version

        if model == 'salt2-extended':
            model_min=300.
            model_max=180000.
            wave_min=3000.
            wave_max=11501.

        if model=='salt2':
            model_min=2000.
            model_max=9200.0
            wave_min=model_min
            wave_max=model_max

        wave= np.arange(wave_min,wave_max,1.)
        
        sn_type='Ia'
        source=sncosmo.get_source(model,version=version)
        ra_field=0.
        dec_field=0.
        
        table_obs.sort(self.mjd_name)
       
        for iv,param in enumerate(parameters):
            #mysn=Simul_Fit_SN(param['DayMax'],param['Color'],param['X1'],param['z'],table_obs,ra=param['ra'],dec=param['dec'])
            table_LC=Table(names=('idSN','filter','expMJD','visitExpTime','FWHMeff','moon_frac','filtSkyBrightness','kAtm','airmass','fiveSigmaDepth','Nexp','e_per_sec','e_per_sec_err'), dtype=('i8','S7','f8', 'f8','f8','f8', 'f8','f8','i8','f8','f8','f8','f8'))


            lumidist=self.astropy_cosmo.luminosity_distance(param['z']).value*1.e3
       
            X0 = self.X0_norm / lumidist** 2
            X0 *= np.power(10., 0.4*(alpha*param['X1'] -beta*param['Color']))

            print 'X0 val',X0

            SN=sncosmo.Model(source=source,effects=[dust, dust],
                              effect_names=['host', 'mw'],
                              effect_frames=['rest', 'obs'])
            SN.set(z=param['z'])
            SN.set(t0=param['DayMax'])
            SN.set(c=param['Color'])
            SN.set(x1=param['X1'])
            SN.set(x0=X0)
            
            #SN.set_source_peakabsmag(peakAbsMagBesselB, 'bessellB', 'vega',cosmo=mycosmology)
            fluxes=10.*SN.flux(table_obs[self.mjd_name],wave)
            wavelength=wave/10. 
            wavelength=np.repeat(wavelength[np.newaxis,:], len(fluxes), 0)
            SED_time = Sed(wavelen=wavelength, flambda=fluxes)
           
            self.params.add_row((param['DayMax'],param['Color'],param['X1'],param['z'],ra_field,dec_field,'unkown',None,sn_type,model,version,SN._source.peakmag('bessellb','vega'),SN.get('x0'),lumidist))
            
            for i in range(len(SED_time.wavelen)):
                obs=table_obs[i]
                sed=Sed(wavelen=SED_time.wavelen[i],flambda=SED_time.flambda[i])
                visittime=obs['exptime']
                filtre=obs['band'][-1]
                photParams = PhotometricParameters(nexp=visittime/15.)
                e_per_sec = sed.calcADU(bandpass=self.transmission.lsst_atmos_aerosol[filtre], photParams=photParams) #number of ADU counts for expTime
                e_per_sec/=visittime/photParams.gain
                
                flux_SN=sed.calcFlux(bandpass=self.transmission.lsst_atmos_aerosol[filtre])

                FWHMeff=obs[self.FWHMeff]
                if flux_SN >0:
                    #print 'hello flux',flux_SN,fluxes[i]
                    mag_SN=-2.5 * np.log10(flux_SN / 3631.0)
                    m5_calc,snr_m5_through=self.Get_m5(filtre,mag_SN,obs['sky'],photParams,FWHMeff)
                    
                    table_LC.add_row((iv,'LSST::'+filtre,obs[self.mjd_name],visittime,FWHMeff,obs['moon_frac'],obs['sky'],obs['kAtm'],obs['airmass'],obs['m5sigmadepth'],obs['Nexp'],e_per_sec,e_per_sec/snr_m5_through))

            self.lc.append(table_LC)
    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)
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
示例#40
0
    def X0_norm(self):

        name = 'STANDARD'
        band = 'B'
        thedir = '../Cosmo_Maf'
        #thedir='.'

        os.environ[name] = thedir + '/Instruments/Landolt'

        trans_standard = Throughputs(through_dir='STANDARD',
                                     telescope_files=[],
                                     filter_files=['sb_-41A.dat'],
                                     atmos=False,
                                     aerosol=False,
                                     filterlist=('A'),
                                     wave_min=3559,
                                     wave_max=5559)

        mag, spectrum_file = self.Get_Mag(
            thedir + '/MagSys/VegaBD17-2008-11-28.dat', name, band)

        #print 'alors mag',mag, spectrum_file
        sed = Sed()

        sed.readSED_fnu(filename=thedir + '/' + spectrum_file)
        CLIGHT_A_s = 2.99792458e18  # [A/s]
        HPLANCK = 6.62606896e-27
        sedb = Sed(wavelen=sed.wavelen,
                   flambda=sed.wavelen * sed.fnu / (CLIGHT_A_s * HPLANCK))
        #print 'alors man',sed.wavelen*sed.fnu/(CLIGHT_A_s * HPLANCK)
        flux = self.calcInteg(bandpass=trans_standard.system['A'],
                              signal=sedb.flambda,
                              wavelen=sedb.wavelen)

        zp = 2.5 * np.log10(flux) + mag
        flux_at_10pc = np.power(10., -0.4 * (self.peakAbsMagBesselB - zp))

        #print 'zp',zp,flux_at_10pc

        source = sncosmo.get_source(self.model, version=self.version)
        SN = sncosmo.Model(source=source)

        SN.set(z=0.)
        SN.set(t0=0)
        SN.set(c=self.param['Color'])
        SN.set(x1=self.param['X1'])
        SN.set(x0=1)

        fluxes = 10. * SN.flux(0., self.wave)

        wavelength = self.wave / 10.
        SED_time = Sed(wavelen=wavelength, flambda=fluxes)

        expTime = 30.
        photParams = PhotometricParameters(nexp=expTime / 15.)
        trans = Bandpass(wavelen=trans_standard.system['A'].wavelen / 10.,
                         sb=trans_standard.system['A'].sb)
        e_per_sec = SED_time.calcADU(
            bandpass=trans,
            photParams=photParams)  #number of ADU counts for expTime
        #e_per_sec = sed.calcADU(bandpass=self.transmission.lsst_atmos[filtre], photParams=photParams)
        e_per_sec /= expTime / photParams.gain * photParams.effarea
        #print 'hello',e_per_sec
        """
        SN.set(c=self.param['Color'])
        SN.set(x1=self.param['X1'])
        """

        #print 'My zp',zp,flux
        return flux_at_10pc * 1.E-4 / e_per_sec
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
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