예제 #1
0
    def __init__(self, metricName='TDEsPopMetric', mjdCol='observationStartMJD', m5Col='fiveSigmaDepth',
                 filterCol='filter', nightCol='night', ptsNeeded=2, file_list=None, mjd0=59853.5,
                 **kwargs):
        maps = ['DustMap']
        self.mjdCol = mjdCol
        self.m5Col = m5Col
        self.filterCol = filterCol
        self.nightCol = nightCol
        self.ptsNeeded = ptsNeeded

        self.lightcurves = Tde_lc(file_list=file_list)
        self.mjd0 = mjd0

        waveMins = {'u': 330., 'g': 403., 'r': 552., 'i': 691., 'z': 818., 'y': 950.}
        waveMaxes = {'u': 403., 'g': 552., 'r': 691., 'i': 818., 'z': 922., 'y': 1070.}

        self.a = {}
        self.b = {}
        for filtername in waveMins.keys():
            testsed = Sed()
            testsed.setFlatSED(wavelen_min=waveMins[filtername],
                               wavelen_max=waveMaxes[filtername],
                               wavelen_step=1)
            self.a[filtername], self.b[filtername] = testsed.setupCCM_ab()
        self.R_v = 3.1

        cols = [self.mjdCol, self.m5Col, self.filterCol, self.nightCol]
        super(TdePopMetric, self).__init__(col=cols, units='Detected, 0 or 1',
                                           metricName=metricName, maps=maps,
                                           **kwargs)
예제 #2
0
    def ZP_filtre(self, filtre):

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

        Zb = 181.8 * np.power(self.Diameter / 6.5, 2.) * self.Tb[filtre]
        mbZ = 25. + 2.5 * np.log10(Zb)
        filtre_trans = self.throughputs.system[filtre]
        wavelen_min, wavelen_max, wavelen_step = filtre_trans.getWavelenLimits(
            None, None, None)
        bandpass = Bandpass(wavelen=filtre_trans.wavelen, sb=filtre_trans.sb)
        flatSed = Sed()
        flatSed.setFlatSED(wavelen_min, wavelen_max, wavelen_step)
        flux0 = np.power(10., -0.4 * mbZ)
        flatSed.multiplyFluxNorm(flux0)
        counts = flatSed.calcADU(
            bandpass,
            photParams=self.photParams)  #number of counts for exptime
        self.data['zp'][filtre] = mbZ
        #print 'hello',counts/self.photParams.exptime
        self.data['counts_zp'][filtre] = counts / self.photParams.exptime
예제 #3
0
    def __init__(self, metricName='plasticc_transient', mjdCol='observationStartMJD', m5Col='fiveSigmaDepth',
                 filterCol='filter', color_gap=0.5, pre_slope_range=0.3,
                 days_around_peak=200, r_mag_limit=28, nbins=10, nsamples=5, maps=['DustMap'], apply_dust=True,
                 units='fraction', **kwargs):
        self.mjdCol = mjdCol
        self.m5Col = m5Col
        self.filterCol = filterCol
        self.color_gap = color_gap
        self.pre_slope_range = pre_slope_range
        self.days_around_peak = days_around_peak
        self.rmag_limit = r_mag_limit
        self.nbins = nbins
        self.nsamples = nsamples
        self.apply_dust = apply_dust
        super(Plasticc_metric, self).__init__(col=[self.mjdCol, self.m5Col, self.filterCol],
                                              metricName=metricName, maps=maps, units=units, **kwargs)

        # Let's set up the dust stuff
        waveMins = {'u': 330., 'g': 403., 'r': 552., 'i': 691., 'z': 818., 'y': 950.}
        waveMaxes = {'u': 403., 'g': 552., 'r': 691., 'i': 818., 'z': 922., 'y': 1070.}

        self.a_extinc = {}
        self.b_extinc = {}
        for filtername in waveMins:
            testsed = Sed()
            testsed.setFlatSED(wavelen_min=waveMins[filtername],
                               wavelen_max=waveMaxes[filtername], wavelen_step=1)
            self.a_extinc[filtername], self.b_extinc[filtername] = testsed.setupCCM_ab()
        self.R_v = 3.1
예제 #4
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
예제 #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 __init__(self, m5Col='fiveSigmaDepth', units='mag', maps=['DustMap'],
                 lsstFilter='r', wavelen_min=None , wavelen_max=None , wavelen_step=1., **kwargs ):
        """
        Args:
            m5Col (str): Column name that ('fiveSigmaDepth')
            units (str): units of the metric ('mag')
            maps (list): List of maps to use with the metric (['DustMap'])
            lsstFilter (str): Which LSST filter to calculate m5 for
            wavelen_min (float): Minimum wavength of your filter (None)
            wavelen_max (float): (None)
            wavelen_step (float): (1.)
            **kwargs:
        """

        waveMins={'u':330.,'g':403.,'r':552.,'i':691.,'z':818.,'y':950.}
        waveMaxes={'u':403.,'g':552.,'r':691.,'i':818.,'z':922.,'y':1070.}

        if lsstFilter is not None:
            wavelen_min = waveMins[lsstFilter]
            wavelen_max = waveMaxes[lsstFilter]

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

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

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

        # Set up internal values for the dust extinction.
        testsed = Sed()
        testsed.setFlatSED(wavelen_min=wavelen_min, wavelen_max=wavelen_max, wavelen_step=1.0)
        testbandpass = Bandpass(wavelen_min=wavelen_min, wavelen_max=wavelen_max, wavelen_step=1.0)
        testbandpass.setBandpass(wavelen=testsed.wavelen,
                                 sb=np.ones(len(testsed.wavelen)))
        self.R_v = 3.1
        self.ref_ebv = 1.0
        # Calculate non-dust-extincted magnitude
        flatmag = testsed.calcMag(testbandpass)
        # Add dust
        self.a, self.b = testsed.setupCCM_ab()
        testsed.addDust(self.a, self.b, ebv=self.ref_ebv, R_v=self.R_v)
        # Calculate difference due to dust when EBV=1.0 (m_dust = m_nodust - Ax, Ax > 0)
        self.Ax1 = testsed.calcMag(testbandpass) - flatmag
        # We will call Coaddm5Metric to calculate the coadded depth. Set it up here.
        self.Coaddm5Metric = Coaddm5Metric(m5Col=m5Col)
예제 #8
0
    def __init__(self,
                 m5Col='fiveSigmaDepth',
                 units='mag',
                 lsstFilter='i',
                 wavelen_min=None,
                 wavelen_max=None,
                 wavelen_step=1.,
                 extinction_cut=0.2,
                 depth_cut=26,
                 **kwargs):
        """
        Args: 
            m5Col (str): Column name that ('fiveSigmaDepth')
            units (str): units of the metric ('mag')
            lsstFilter (str): Which LSST filter to calculate m5 for
            wavelen_min (float): Minimum wavength of your filter (None)
            wavelen_max (float): (None)
            wavelen_step (float): (1.)
            **kwargs:
        """
        maps = ['DustMap']
        waveMins = {
            'u': 330.,
            'g': 403.,
            'r': 552.,
            'i': 691.,
            'z': 818.,
            'y': 950.
        }
        waveMaxes = {
            'u': 403.,
            'g': 552.,
            'r': 691.,
            'i': 818.,
            'z': 922.,
            'y': 1070.
        }

        if lsstFilter is not None:
            wavelen_min = waveMins[lsstFilter]
            wavelen_max = waveMaxes[lsstFilter]

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

        testsed = Sed()
        testsed.setFlatSED(wavelen_min=wavelen_min,
                           wavelen_max=wavelen_max,
                           wavelen_step=1)
        self.a, self.b = testsed.setupCCM_ab()
        self.R_v = 3.1
        self.Coaddm5Metric = Coaddm5Metric(m5Col=m5Col)

        self.extinction_cut = extinction_cut
        self.depth_cut = depth_cut
예제 #9
0
 def Get_m5(self,filtre,mag_SN,msky,photParams,FWHMeff):
     
     wavelen_min, wavelen_max, wavelen_step=self.transmission.lsst_system[filtre].getWavelenLimits(None,None,None)
             
     flatSed = Sed()
     flatSed.setFlatSED(wavelen_min, wavelen_max, wavelen_step)
     flux0=np.power(10.,-0.4*msky)
     flatSed.multiplyFluxNorm(flux0)
     m5_calc=SignalToNoise.calcM5(flatSed,self.transmission.lsst_atmos_aerosol[filtre],self.transmission.lsst_system[filtre],photParams=photParams,FWHMeff=FWHMeff)
     snr_m5_through,gamma_through=SignalToNoise.calcSNR_m5(mag_SN,self.transmission.lsst_atmos_aerosol[filtre],m5_calc,photParams)
     
     return m5_calc,snr_m5_through
예제 #10
0
    def testVerboseSNR(self):
        """
        Make sure that calcSNR_sed has everything it needs to run in verbose mode
        """
        photParams = PhotometricParameters()

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

        snr.calcSNR_sed(spectrum, self.bpList[0], self.skySed,
                        self.hardwareList[0], photParams, FWHMeff=0.7, verbose=True)
예제 #11
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
예제 #12
0
    def testVerboseSNR(self):
        """
        Make sure that calcSNR_sed has everything it needs to run in verbose mode
        """
        defaults = LSSTdefaults()
        photParams = PhotometricParameters()

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

        snr.calcSNR_sed(spectrum, self.bpList[0], self.skySed,
                        self.hardwareList[0], photParams, seeing=0.7, verbose=True)
예제 #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)
예제 #14
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
예제 #15
0
def make_response_func(magnorm=16., filename='starSED/wDs/bergeron_14000_85.dat_14200.gz',
                       savefile='gaia_response.npz', noise=1, count_min=8.,
                       bluecut=700., redcut=650):
    """
    Declare some stars as "standards" and build a simple GAIA response function?

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

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

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

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

    np.savez(savefile, red_response=red_response, blue_response=blue_response,
             red_wavelen=gaia_obs['RP_wave'], blue_wavelen=gaia_obs['BP_wave'])
예제 #16
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
예제 #17
0
    def testMagError(self):
        """
        Make sure that calcMagError_sed and calcMagError_m5
        agree to within 0.001
        """
        defaults = LSSTdefaults()
        photParams = PhotometricParameters()

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

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

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

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

                FWHMeff = defaults.FWHMeff(filterName)

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

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

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

                self.assertAlmostEqual(sigma_m5, sigma_sed, 3)
예제 #18
0
    def CalcMyABMagnitudesError_filter(self, band, SkyBrightnessMag, FWHMGeom):
        """
        CalcMyABMagnitudesError_filter(self,band,SkyBrightnessMag,FWHMGeom)
        
        - author : Sylvie Dagoret-Campagne
        - affiliation : LAL/IN2P3/CNRS/FRANCE
        - date   : July 5th 2018
        
        Calculate magnitude errors for one band.
        
        Input args:
        - band : filter band
        - SkyBrighnessMag : Sky Brighness Magnitude in the band
        - FWHMGeom : Geometrical PSF in the band
        
        """

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

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

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

        photParams = PhotometricParameters(bandpass=band)

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

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

        return mag_err
예제 #19
0
    def testMagError(self):
        """
        Make sure that calcMagError_sed and calcMagError_m5
        agree to within 0.001
        """
        defaults = LSSTdefaults()
        photParams = PhotometricParameters()

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

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

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

                seeing = defaults.seeing(filterName)

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

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

            magSed = numpy.array(magSed)

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


            numpy.testing.assert_array_almost_equal(magM5, magSed, decimal=3)
예제 #20
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
예제 #21
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
예제 #22
0
    def __init__(self, m5Col='fiveSigmaDepth', units='mag', maps=['DustMap'],
                 lsstFilter='r', wavelen_min=None , wavelen_max=None , wavelen_step=1., **kwargs ):
        """

        """

        waveMins={'u':330.,'g':403.,'r':552.,'i':691.,'z':818.,'y':950.}
        waveMaxes={'u':403.,'g':552.,'r':691.,'i':818.,'z':922.,'y':1070.}

        if lsstFilter is not None:
            wavelen_min = waveMins[lsstFilter]
            wavelen_max = waveMaxes[lsstFilter]

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

        testsed = Sed()
        testsed.setFlatSED(wavelen_min = wavelen_min,
                           wavelen_max = wavelen_max, wavelen_step = 1)
        self.a,self.b = testsed.setupCCMab()
        self.R_v = 3.1
        self.Coaddm5Metric = Coaddm5Metric(m5Col=m5Col)
예제 #23
0
    def __init__(self, R_v=3.1, bandpassDict=None, ref_ebv=1.):
        # Calculate dust extinction values
        self.Ax1 = {}
        if bandpassDict is None:
            bandpassDict = BandpassDict.loadTotalBandpassesFromFiles(
                ['u', 'g', 'r', 'i', 'z', 'y'])

        for filtername in bandpassDict:
            wavelen_min = bandpassDict[filtername].wavelen.min()
            wavelen_max = bandpassDict[filtername].wavelen.max()
            testsed = Sed()
            testsed.setFlatSED(wavelen_min=wavelen_min,
                               wavelen_max=wavelen_max,
                               wavelen_step=1.0)
            self.ref_ebv = ref_ebv
            # Calculate non-dust-extincted magnitude
            flatmag = testsed.calcMag(bandpassDict[filtername])
            # Add dust
            a, b = testsed.setupCCM_ab()
            testsed.addDust(a, b, ebv=self.ref_ebv, R_v=R_v)
            # Calculate difference due to dust when EBV=1.0 (m_dust = m_nodust - Ax, Ax > 0)
            self.Ax1[filtername] = testsed.calcMag(
                bandpassDict[filtername]) - flatmag
    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)
예제 #25
0
    def testMagError(self):
        """
        Make sure that calcMagError_sed and calcMagError_m5
        agree to within 0.001
        """
        defaults = LSSTdefaults()
        photParams = PhotometricParameters()

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

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

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

                seeing = defaults.seeing(filterName)

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

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

            magSed = numpy.array(magSed)

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

            numpy.testing.assert_array_almost_equal(magM5, magSed, decimal=3)
    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)
예제 #27
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
예제 #28
0
    def CalcMyABMagnitudesErrors(self):
        """
        CalcMyABMagnitudesErrors(self)
        
        - author : Sylvie Dagoret-Campagne
        - affiliation : LAL/IN2P3/CNRS/FRANCE
        - date   : July 4th 2018
        
        Calculate magnitude errors for all bands
        
        """
        all_magABErr = []

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

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

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

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

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

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

            all_magABErr.append(magerr)
        return np.array(all_magABErr)
예제 #29
0
    def testMagError(self):
        """
        Make sure that calcMagError_sed and calcMagError_m5
        agree to within 0.001
        """
        defaults = LSSTdefaults()
        photParams = PhotometricParameters()

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

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

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

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

                FWHMeff = defaults.FWHMeff(filterName)

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

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

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

                self.assertAlmostEqual(sigma_m5, sigma_sed, 3)
예제 #30
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
예제 #31
0
    for f in filterlist:
        mags1[f][i] = tmpgal.calcMag(lsstbp[f])
dt, t = dtime(t)
print "Calculating dust/redshift/dust/fluxnorm/%d magnitudes for %d galaxies took %f s" \
      %(len(filterlist), num_gal, dt)

# For next test: want to also do all the same steps, but in an optimized form. This means
# doing some things that Sed does 'behind the scenes' explicitly, but also means the code may be a little
# harder to read at first.
# First: calculate internal a/b on wavelength range required for internal dust extinction.
a_int, b_int = gals[
    gallist[0]].setupCCMab()  # this is a/b on native galaxy sed range.
# Next: calculate milky way a/b on wavelength range required for calculating magnitudes - i.e. 300 to 1200 nm.
tmpgal = Sed()
tmpgal.setFlatSED(wavelen_min=wavelen_min,
                  wavelen_max=wavelen_max,
                  wavelen_step=wavelen_step)
a_mw, b_mw = tmpgal.setupCCMab()  # so this is a/b on native MW bandpass range.
# Also: set up phi for each bandpass - ahead of time. And set up a list of bandpasses, then create phiarray
# and dlambda to set up for manyMagCalc method.
bplist = []
for f in filterlist:
    lsstbp[f].sbTophi()
    bplist.append(lsstbp[f])
phiarray, dlambda = tmpgal.setupPhiArray(bplist)
# Set up dictionary + arrays to hold calculated magnitude information.
mags2 = {}
for f in filterlist:
    mags2[f] = numpy.zeros(num_gal, dtype='float')
# For each galaxy (in num_gal's), apply internal dust, redshift, resample to 300-1200 nm, apply MW dust on
#   shorter (and standardized) wavelength range, fluxnorm, and then calculate mags using manyMagCalc.
예제 #32
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
예제 #33
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())
예제 #34
0
    def Simulate_and_Fit_LC(self, observations, transmission, zmin, zmax):

        #print 'start Simulation',time.time()-self.start_time
        #print 'time',observations['expMJD'],observations['filter']

        #print 'simulate and fit'
        ra = observations[self.fieldRA][0]
        dec = observations[self.fieldDec][0]

        if self.SN.sn_type == 'Ia':
            mbsim = self.SN.SN._source.peakmag('bessellb', 'vega')
        else:
            mbsim = -1

        #This will be the data for sncosmo fitting
        table_for_fit = {}
        table_for_fit['error_coadd_opsim'] = Table(
            names=('time', 'flux', 'fluxerr', 'band', 'zp', 'zpsys'),
            dtype=('f8', 'f8', 'f8', 'S7', 'f4', 'S4'))
        table_for_fit['error_coadd_through'] = Table(
            names=('time', 'flux', 'fluxerr', 'band', 'zp', 'zpsys'),
            dtype=('f8', 'f8', 'f8', 'S7', 'f4', 'S4'))
        """
        table_for_fit['error_opsim'] = Table(names=('time','flux','fluxerr','band','zp','zpsys'), dtype=('f8', 'f8','f8','S7','f4','S4'))
        table_for_fit['error_through'] = Table(names=('time','flux','fluxerr','band','zp','zpsys'), dtype=('f8', 'f8','f8','S7','f4','S4'))
        """
        mytype = [('obsHistID', np.int), ('filtSkyBrightness', np.float),
                  ('airmass', np.float), ('moonPhase', np.float),
                  ('fieldRA', np.float), ('fieldDec', np.float),
                  ('visitExpTime', np.float), ('expDate', np.int),
                  ('filter', np.dtype('a15')), ('fieldID', np.int),
                  ('fiveSigmaDepth', np.float), ('ditheredDec', np.float),
                  ('expMJD', np.float), ('ditheredRA', np.float),
                  ('rawSeeing', np.float), ('flux', np.float),
                  ('err_flux', np.float), ('err_flux_opsim', np.float),
                  ('err_flux_through', np.float), ('finSeeing', np.float),
                  ('katm_opsim', np.float), ('katm_calc', np.float),
                  ('m5_calc', np.float), ('Tb', np.float),
                  ('Sigmab', np.float), ('Cm', np.float), ('dCm', np.float),
                  ('mag_SN', np.float), ('snr_m5_through', np.float),
                  ('snr_m5_opsim', np.float), ('gamma_through', np.float),
                  ('gamma_opsim', np.float), ('snr_SED', np.float)]

        myobservations = np.zeros((60, 1), dtype=mytype)

        #print 'Nobservations',len(observations)
        nobs = -1
        for obs in observations:

            nobs += 1
            filtre = obs['filter']
            if len(myobservations) <= nobs:
                myobservations = np.resize(myobservations,
                                           (len(myobservations) + 100, 1))

            for name in self.cols_restricted:
                myobservations[name][nobs] = obs[name]

            seeing = obs['rawSeeing']
            time_obs = obs['expMJD']
            m5_opsim = obs['fiveSigmaDepth']
            sed_SN = self.SN.get_SED(time_obs)

            transmission.Load_Atmosphere(obs['airmass'])
            flux_SN = sed_SN.calcFlux(
                bandpass=transmission.lsst_atmos_aerosol[filtre])

            myup = 0
            Tb = 0
            Sigmab = 0
            katm = 0

            mbsky_through = 0
            """
            Filter_Wavelength_Correction = np.power(500.0 / self.params.filterWave[filtre], 0.3)
            Airmass_Correction = math.pow(obs['airmass'],0.6)
            FWHM_Sys = self.params.FWHM_Sys_Zenith * Airmass_Correction
            FWHM_Atm = seeing * Filter_Wavelength_Correction * Airmass_Correction
            finSeeing = self.params.scaleToNeff * math.sqrt(np.power(FWHM_Sys,2) + self.params.atmNeffFactor * np.power(FWHM_Atm,2))
            

            Tscale = obs['visitExpTime']/ 30.0 * np.power(10.0, -0.4*(obs['filtSkyBrightness'] - self.params.msky[filtre]))
            dCm = self.params.dCm_infinity[filtre] - 1.25*np.log10(1 + np.power(10.,0.8*self.params.dCm_infinity[filtre]- 1.)/Tscale)

            m5_recalc=dCm+self.params.Cm[filtre]+0.5*(obs['filtSkyBrightness']-21.)+2.5*np.log10(0.7/finSeeing)-self.params.kAtm[filtre]*(obs['airmass']-1.)+1.25*np.log10(obs['visitExpTime']/30.)
            
            """
            """
            myobservations['Cm'][nobs]=self.params.Cm[filtre]
            myobservations['dCm'][nobs]=dCm
            myobservations['finSeeing'][nobs]=finSeeing
            myobservations['Tb'][nobs]=Tb
            myobservations['Sigmab'][nobs]=Sigmab
            myobservations['katm_calc'][nobs]=katm
            myobservations['katm_opsim'][nobs]=self.params.kAtm[filtre] 
            """
            #print 'Flux',time.time()-self.start_time
            if flux_SN > 0:

                wavelen_min, wavelen_max, wavelen_step = transmission.lsst_system[
                    filtre].getWavelenLimits(None, None, None)
                flatSed = Sed()
                flatSed.setFlatSED(wavelen_min, wavelen_max, wavelen_step)
                flux0 = np.power(10., -0.4 * obs['filtSkyBrightness'])
                flatSed.multiplyFluxNorm(flux0)
                mag_SN = -2.5 * np.log10(flux_SN / 3631.0)

                #FWHMeff = SignalToNoise.FWHMgeom2FWHMeff(finSeeing)
                FWHMeff = obs['FWHMeff']
                photParams = PhotometricParameters(nexp=obs['visitExpTime'] /
                                                   15.)

                m5_calc = SignalToNoise.calcM5(
                    flatSed,
                    transmission.lsst_atmos_aerosol[filtre],
                    transmission.lsst_system[filtre],
                    photParams=photParams,
                    FWHMeff=FWHMeff)
                snr_m5_through, gamma_through = SignalToNoise.calcSNR_m5(
                    mag_SN, transmission.lsst_atmos_aerosol[filtre], m5_calc,
                    photParams)
                m5_opsim += 1.25 * np.log10(obs['visitExpTime'] / 30.)
                snr_m5_opsim, gamma_opsim = SignalToNoise.calcSNR_m5(
                    mag_SN, transmission.lsst_atmos_aerosol[filtre], m5_opsim,
                    photParams)

                err_flux_SN = 0
                err_flux_SN_opsim = flux_SN / snr_m5_opsim
                err_flux_SN_through = flux_SN / snr_m5_through

                myobservations['mag_SN'][nobs] = mag_SN
                myobservations['flux'][nobs] = flux_SN
                myobservations['err_flux'][nobs] = err_flux_SN
                myobservations['err_flux_opsim'][nobs] = err_flux_SN_opsim
                myobservations['err_flux_through'][nobs] = err_flux_SN_through
                myobservations['m5_calc'][nobs] = m5_calc
                myobservations['snr_m5_through'][nobs] = snr_m5_through
                myobservations['snr_m5_opsim'][nobs] = snr_m5_opsim
                myobservations['gamma_through'][nobs] = gamma_through
                myobservations['gamma_opsim'][nobs] = gamma_opsim
                #myobservations['snr_SED'][nobs]=snr_SN

                #print 'SNR',flux_SN,flux_SN/err_flux_SN,flux_SN/err_flux_SN_opsim
                #if flux_SN/err_flux_SN >=5:
                #table_for_fit['error_calc'].add_row((time_obs,flux_SN,err_flux_SN,'LSST::'+filtre,25,'ab'))
                #if flux_SN/err_flux_SN_opsim >=5.:
                table_for_fit['error_coadd_opsim'].add_row(
                    (time_obs, flux_SN, err_flux_SN_opsim, 'LSST::' + filtre,
                     25, 'ab'))
                table_for_fit['error_coadd_through'].add_row(
                    (time_obs, flux_SN, err_flux_SN_through, 'LSST::' + filtre,
                     25, 'ab'))
                #print 'Getting fluxes and errors',time.time()-self.thetime,filtre,nobs
            else:
                err_flux_SN = -999.
                err_flux_SN_opsim = -999.
                myobservations['mag_SN'][nobs] = -999
                myobservations['flux'][nobs] = flux_SN
                myobservations['err_flux'][nobs] = -999.
                myobservations['err_flux_opsim'][nobs] = -999.
                myobservations['err_flux_through'][nobs] = -999.
                myobservations['m5_calc'][nobs] = -999.
                myobservations['snr_m5_through'][nobs] = -999
                myobservations['snr_m5_opsim'][nobs] = -999
                myobservations['gamma_through'][nobs] = -999
                myobservations['gamma_opsim'][nobs] = -999
                myobservations['snr_SED'][nobs] = -999

        myobservations = np.resize(myobservations, (nobs + 1, 1))
        """
        print 'Preparing table_for_fit',time.time()-self.start_time
        for band in ['u','g','r','i','z','y']:
            selb=table_for_fit['error_opsim'][np.where(table_for_fit['error_opsim']['band']=='LSST::'+band)]
            selc=table_for_fit['error_through'][np.where(table_for_fit['error_through']['band']=='LSST::'+band)]

            table_for_fit['error_coadd_opsim']=vstack([table_for_fit['error_coadd_opsim'],self.Get_coadd(selb)])
            table_for_fit['error_coadd_through']=vstack([table_for_fit['error_coadd_through'],self.Get_coadd(selc)])
        """

        #print 'There we go fitting',time.time()-self.thetime
        dict_fit = {}
        #for val in ['error_calc','error_coadd_calc','error_opsim','error_coadd_opsim']:

        for val in ['error_coadd_opsim', 'error_coadd_through']:
            #print 'Go for fit',time.time()-self.start_time
            dict_fit[val] = {}
            dict_fit[val]['sncosmo_fitted'] = {}
            dict_fit[val]['table_for_fit'] = table_for_fit[val]
            #print 'fit',val,time.time()-self.thetime
            res, fitted_model, mbfit, fit_status = self.Fit_SN(
                table_for_fit[val], zmin, zmax)
            if res is not None:
                dict_fit[val]['sncosmo_res'] = res
                #self.dict_fit[val]['fitted_model']=fitted_model
                for i, par in enumerate(fitted_model.param_names):
                    dict_fit[val]['sncosmo_fitted'][
                        par] = fitted_model.parameters[i]
                dict_fit[val]['mbfit'] = mbfit
            dict_fit[val]['fit_status'] = fit_status
            #print 'end of Fit',time.time()-self.start_time

        return dict_fit, mbsim, myobservations
예제 #35
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())
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
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
예제 #38
0
    def Simulate_and_Fit_LC(self, observations, transmission, zmin, zmax):

        #print 'time',observations['expMJD'],observations['filter']

        #print 'simulate and fit'
        ra = observations[self.fieldRA][0]
        dec = observations[self.fieldDec][0]

        if self.SN.sn_type == 'Ia':
            mbsim = self.SN.SN._source.peakmag('bessellb', 'vega')
        else:
            mbsim = -1

        #This will be the data for sncosmo fitting
        table_for_fit = {}
        table_for_fit['error_calc'] = Table(names=('time', 'flux', 'fluxerr',
                                                   'band', 'zp', 'zpsys'),
                                            dtype=('f8', 'f8', 'f8', 'S7',
                                                   'f4', 'S4'))
        table_for_fit['error_coadd_calc'] = Table(
            names=('time', 'flux', 'fluxerr', 'band', 'zp', 'zpsys'),
            dtype=('f8', 'f8', 'f8', 'S7', 'f4', 'S4'))
        table_for_fit['error_opsim'] = Table(names=('time', 'flux', 'fluxerr',
                                                    'band', 'zp', 'zpsys'),
                                             dtype=('f8', 'f8', 'f8', 'S7',
                                                    'f4', 'S4'))
        table_for_fit['error_coadd_opsim'] = Table(
            names=('time', 'flux', 'fluxerr', 'band', 'zp', 'zpsys'),
            dtype=('f8', 'f8', 'f8', 'S7', 'f4', 'S4'))
        table_for_fit['error_through'] = Table(
            names=('time', 'flux', 'fluxerr', 'band', 'zp', 'zpsys'),
            dtype=('f8', 'f8', 'f8', 'S7', 'f4', 'S4'))
        table_for_fit['error_coadd_through'] = Table(
            names=('time', 'flux', 'fluxerr', 'band', 'zp', 'zpsys'),
            dtype=('f8', 'f8', 'f8', 'S7', 'f4', 'S4'))

        mytype = [('obsHistID', np.int), ('filtSkyBrightness', np.float),
                  ('airmass', np.float), ('moonPhase', np.float),
                  ('fieldRA', np.float), ('fieldDec', np.float),
                  ('visitExpTime', np.float), ('expDate', np.int),
                  ('filter', np.dtype('a15')), ('fieldID', np.int),
                  ('fiveSigmaDepth', np.float), ('ditheredDec', np.float),
                  ('expMJD', np.float), ('ditheredRA', np.float),
                  ('rawSeeing', np.float), ('flux', np.float),
                  ('err_flux', np.float), ('err_flux_opsim', np.float),
                  ('err_flux_through', np.float), ('finSeeing', np.float),
                  ('katm_opsim', np.float), ('katm_calc', np.float),
                  ('m5_calc', np.float), ('Tb', np.float),
                  ('Sigmab', np.float), ('Cm', np.float), ('dCm', np.float),
                  ('mag_SN', np.float), ('snr_m5_through', np.float),
                  ('snr_m5_opsim', np.float), ('gamma_through', np.float),
                  ('gamma_opsim', np.float), ('snr_SED', np.float)]

        myobservations = np.zeros((60, 1), dtype=mytype)

        #print 'Nobservations',len(observations)
        nobs = -1
        for filtre in self.filterNames:
            obs_filtre = observations[np.where(
                observations['filter'] == filtre)]
            #print 'ehehe',obs_filtre

            for obs in obs_filtre:

                nobs += 1

                if len(myobservations) <= nobs:
                    myobservations = np.resize(myobservations,
                                               (len(myobservations) + 100, 1))

                for name in observations.dtype.names:
                    myobservations[name][nobs] = obs[name]

                #print 'time uu',obs['expMJD']
                seeing = obs['rawSeeing']
                #seeing=obs['finSeeing']
                time_obs = obs['expMJD']
                m5_opsim = obs['fiveSigmaDepth']

                #print 'getting SED'
                sed_SN = self.SN.get_SED(time_obs)
                #print 'got SED',sed_SN.wavelen,sed_SN.flambda,obs['expMJD']
                """
                outf = open('SN_'+str(time)+'.dat', 'wb')
                for i,wave in enumerate(sn.SEDfromSNcosmo.wavelen):
                    print >> outf,wave,sn.SEDfromSNcosmo.flambda[i]
                outf.close()
                """
                #print 'loading transmission airmass'
                transmission.Load_Atmosphere(obs['airmass'])
                flux_SN = sed_SN.calcFlux(
                    bandpass=transmission.lsst_atmos_aerosol[filtre])
                #print 'this is my flux',flux_SN
                #flux_SN=sed_SN.calcFlux(bandpass=transmission.lsst_system[filtre]) / 3631.0

                myup = transmission.darksky.calcInteg(
                    transmission.lsst_system[filtre])
                """
                wavelen, sb = transmission.lsst_system[filtre].multiplyThroughputs(transmission.lsst_atmos[filtre].wavelen, transmission.lsst_atmos[filtre].sb)
                lsst_total= Bandpass(wavelen=wavelen, sb=sb)
                """
                Tb = self.Calc_Integ(transmission.lsst_atmos[filtre])
                Sigmab = self.Calc_Integ(transmission.lsst_system[filtre])
                katm = -2.5 * np.log10(Tb / Sigmab)

                mbsky_through = -2.5 * np.log10(myup / (3631. * Sigmab))

                #print 'there mbsky',filtre,mbsky_through,obs['filtSkyBrightness'],katm,self.kAtm[filtre],Tb,Sigmab,obs['airmass']

                Filter_Wavelength_Correction = np.power(
                    500.0 / self.params.filterWave[filtre], 0.3)
                Airmass_Correction = math.pow(obs['airmass'], 0.6)
                FWHM_Sys = self.params.FWHM_Sys_Zenith * Airmass_Correction
                FWHM_Atm = seeing * Filter_Wavelength_Correction * Airmass_Correction
                finSeeing = self.params.scaleToNeff * math.sqrt(
                    np.power(FWHM_Sys, 2) +
                    self.params.atmNeffFactor * np.power(FWHM_Atm, 2))

                #print 'hello pal',filtre,finSeeing,obs['visitExpTime']
                Tscale = obs['visitExpTime'] / 30.0 * np.power(
                    10.0, -0.4 *
                    (obs['filtSkyBrightness'] - self.params.msky[filtre]))
                dCm = self.params.dCm_infinity[filtre] - 1.25 * np.log10(
                    1 + np.power(10., 0.8 * self.params.dCm_infinity[filtre] -
                                 1.) / Tscale)

                m5_recalc = dCm + self.params.Cm[filtre] + 0.5 * (
                    obs['filtSkyBrightness'] - 21.) + 2.5 * np.log10(
                        0.7 / finSeeing) - self.params.kAtm[filtre] * (
                            obs['airmass'] - 1.) + 1.25 * np.log10(
                                obs['visitExpTime'] / 30.)

                myobservations['Cm'][nobs] = self.params.Cm[filtre]
                myobservations['dCm'][nobs] = dCm
                myobservations['finSeeing'][nobs] = finSeeing
                myobservations['Tb'][nobs] = Tb
                myobservations['Sigmab'][nobs] = Sigmab
                myobservations['katm_calc'][nobs] = katm
                myobservations['katm_opsim'][nobs] = self.params.kAtm[filtre]
                wavelen_min, wavelen_max, wavelen_step = transmission.lsst_system[
                    filtre].getWavelenLimits(None, None, None)
                flatSed = Sed()
                flatSed.setFlatSED(wavelen_min, wavelen_max, wavelen_step)
                flux0 = np.power(10., -0.4 * obs['filtSkyBrightness'])
                flatSed.multiplyFluxNorm(flux0)

                if flux_SN > 0:

                    #print 'positive flux',flux_SN
                    mag_SN = -2.5 * np.log10(flux_SN / 3631.0)

                    FWHMeff = SignalToNoise.FWHMgeom2FWHMeff(finSeeing)
                    #FWHMeff = SignalToNoise.FWHMgeom2FWHMeff(seeing)
                    photParams = PhotometricParameters()
                    snr_SN = SignalToNoise.calcSNR_sed(
                        sed_SN,
                        transmission.lsst_atmos_aerosol[filtre],
                        transmission.darksky,
                        transmission.lsst_system[filtre],
                        photParams,
                        FWHMeff=FWHMeff,
                        verbose=False)
                    #m5_calc=SignalToNoise.calcM5(transmission.darksky,transmission.lsst_atmos_aerosol[filtre],transmission.lsst_system[filtre],photParams=photParams,FWHMeff=FWHMeff)
                    m5_calc = SignalToNoise.calcM5(
                        flatSed,
                        transmission.lsst_atmos_aerosol[filtre],
                        transmission.lsst_system[filtre],
                        photParams=photParams,
                        FWHMeff=FWHMeff)
                    snr_m5_through, gamma_through = SignalToNoise.calcSNR_m5(
                        mag_SN, transmission.lsst_atmos_aerosol[filtre],
                        m5_calc, photParams)
                    snr_m5_opsim, gamma_opsim = SignalToNoise.calcSNR_m5(
                        mag_SN, transmission.lsst_atmos_aerosol[filtre],
                        m5_opsim, photParams)

                    #print 'm5 diff',filtre,m5_calc,m5_opsim,m5_calc/m5_opsim,m5_recalc,(m5_opsim/m5_recalc)
                    err_flux_SN = flux_SN / snr_SN
                    err_flux_SN_opsim = flux_SN / snr_m5_opsim
                    err_flux_SN_through = flux_SN / snr_m5_through

                    #print 'test errors',flux_SN,err_flux_SN,err_flux_SN_opsim,err_flux_SN_through,err_flux_SN_through/err_flux_SN_opsim,m5_opsim-m5_calc
                    myobservations['mag_SN'][nobs] = mag_SN
                    myobservations['flux'][nobs] = flux_SN
                    myobservations['err_flux'][nobs] = err_flux_SN
                    myobservations['err_flux_opsim'][nobs] = err_flux_SN_opsim
                    myobservations['err_flux_through'][
                        nobs] = err_flux_SN_through
                    myobservations['m5_calc'][nobs] = m5_calc
                    myobservations['snr_m5_through'][nobs] = snr_m5_through
                    myobservations['snr_m5_opsim'][nobs] = snr_m5_opsim
                    myobservations['gamma_through'][nobs] = gamma_through
                    myobservations['gamma_opsim'][nobs] = gamma_opsim
                    myobservations['snr_SED'][nobs] = snr_SN

                    #print 'SNR',flux_SN,flux_SN/err_flux_SN,flux_SN/err_flux_SN_opsim
                    #if flux_SN/err_flux_SN >=5:
                    #table_for_fit['error_calc'].add_row((time_obs,flux_SN,err_flux_SN,'LSST::'+filtre,25,'ab'))
                    #if flux_SN/err_flux_SN_opsim >=5.:
                    table_for_fit['error_opsim'].add_row(
                        (time_obs, flux_SN, err_flux_SN_opsim,
                         'LSST::' + filtre, 25, 'ab'))
                    table_for_fit['error_through'].add_row(
                        (time_obs, flux_SN, err_flux_SN_through,
                         'LSST::' + filtre, 25, 'ab'))
                    #print 'Getting fluxes and errors',time.time()-self.thetime,filtre,nobs
                else:
                    err_flux_SN = -999.
                    err_flux_SN_opsim = -999.
                    myobservations['mag_SN'][nobs] = -999
                    myobservations['flux'][nobs] = flux_SN
                    myobservations['err_flux'][nobs] = -999.
                    myobservations['err_flux_opsim'][nobs] = -999.
                    myobservations['err_flux_through'][nobs] = -999.
                    myobservations['m5_calc'][nobs] = -999.
                    myobservations['snr_m5_through'][nobs] = -999
                    myobservations['snr_m5_opsim'][nobs] = -999
                    myobservations['gamma_through'][nobs] = -999
                    myobservations['gamma_opsim'][nobs] = -999
                    myobservations['snr_SED'][nobs] = -999

                #print 'flux SN',flux_SN,err_flux_SN,mag_SN,snr_SN,snr_m5_through,snr_m5_opsim

                #t.add_row((time,flux_SN,err_flux_SN,'LSST::'+filtre,0.,'vega'))

                #break

        #t = Table([list(data['time']), list(data['band']),data['flux'],data['fluxerr'],data['flux_aero'],data['fluxerr_aero'],data['fluxerr_new'],data['zp'],data['zpsys']], names=('time','band','flux','fluxerr','flux_aero','fluxerr_aero','fluxerr_new','zp','zpsys'), meta={'name': 'first table'})

        #model.set(z=0.5)
        #print SN.SN

        myobservations = np.resize(myobservations, (nobs + 1, 1))
        #print 'there obs',myobservations
        #print 'Getting coadds',time.time()-self.thetime
        for band in ['u', 'g', 'r', 'i', 'z', 'y']:
            #sela=table_for_fit['error_calc'][np.where(table_for_fit['error_calc']['band']=='LSST::'+band)]
            #sela=sela[np.where(np.logical_and(sela['flux']/sela['fluxerr']>5.,sela['flux']>0.))]
            selb = table_for_fit['error_opsim'][np.where(
                table_for_fit['error_opsim']['band'] == 'LSST::' + band)]
            #selb=selb[np.where(np.logical_and(selb['flux']/selb['fluxerr']>5.,selb['flux']>0.))]
            selc = table_for_fit['error_through'][np.where(
                table_for_fit['error_through']['band'] == 'LSST::' + band)]

            #table_for_fit['error_coadd_calc']=vstack([table_for_fit['error_coadd_calc'],self.Get_coadd(sela)])
            table_for_fit['error_coadd_opsim'] = vstack(
                [table_for_fit['error_coadd_opsim'],
                 self.Get_coadd(selb)])
            table_for_fit['error_coadd_through'] = vstack(
                [table_for_fit['error_coadd_through'],
                 self.Get_coadd(selc)])

        #print 'There we go fitting',time.time()-self.thetime
        dict_fit = {}
        #for val in ['error_calc','error_coadd_calc','error_opsim','error_coadd_opsim']:
        for val in ['error_coadd_opsim', 'error_coadd_through']:
            dict_fit[val] = {}
            dict_fit[val]['sncosmo_fitted'] = {}
            dict_fit[val]['table_for_fit'] = table_for_fit[val]
            #print 'fit',val,time.time()-self.thetime
            res, fitted_model, mbfit, fit_status = self.Fit_SN(
                table_for_fit[val], zmin, zmax)
            if res is not None:
                dict_fit[val]['sncosmo_res'] = res
                #self.dict_fit[val]['fitted_model']=fitted_model
                for i, par in enumerate(fitted_model.param_names):
                    dict_fit[val]['sncosmo_fitted'][
                        par] = fitted_model.parameters[i]
                dict_fit[val]['mbfit'] = mbfit
            dict_fit[val]['fit_status'] = fit_status

        return dict_fit, mbsim, myobservations
예제 #39
0
    for i in range(len(sn_dict)):
        sn_dict[i]['Flux'] = sn_dict[i]['SED'].calcFlux(
            bandpass=transmission.lsst_atmos_aerosol[band])

    Filter_Wavelength_Correction = np.power(500.0 / filterWave[band], 0.3)
    Airmass_Correction = math.pow(obs['airmass'], 0.6)
    FWHM_Sys = FWHM_Sys_Zenith * Airmass_Correction
    FWHM_Atm = seeing * Filter_Wavelength_Correction * Airmass_Correction
    finSeeing = scaleToNeff * math.sqrt(
        np.power(FWHM_Sys, 2) + atmNeffFactor * np.power(FWHM_Atm, 2))

    wavelen_min, wavelen_max, wavelen_step = transmission.lsst_system[
        band].getWavelenLimits(None, None, None)
    flatSed = Sed()
    flatSed.setFlatSED(wavelen_min, wavelen_max, wavelen_step)
    flux0 = np.power(10., -0.4 * obs['filtSkyBrightness'])
    flatSed.multiplyFluxNorm(flux0)

    for i in range(len(sn_dict)):
        flux_SN = sn_dict[i]['Flux']
        if flux_SN >= 0:
            sed_SN = sn_dict[i]['SED']

            mag_SN = -2.5 * np.log10(flux_SN / 3631.0)

            FWHMeff = SignalToNoise.FWHMgeom2FWHMeff(finSeeing)
            photParams = PhotometricParameters()
            snr_SN = SignalToNoise.calcSNR_sed(
                sed_SN,
                transmission.lsst_atmos_aerosol[band],
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
예제 #41
0
def calcM5s(hardware, system, atmos, title='m5'):
    photParams = PhotometricParameters()
    lsstDefaults = LSSTdefaults()
    darksky = Sed()
    darksky.readSED_flambda(os.path.join(os.getenv('SYSENG_THROUGHPUTS_DIR'), 'siteProperties', 'darksky.dat'))
    flatSed = Sed()
    flatSed.setFlatSED()
    m5 = {}
    sourceCounts = {}
    skyCounts = {}
    skyMag = {}
    gamma = {}
    for f in system:
        m5[f] = SignalToNoise.calcM5(darksky, system[f], hardware[f], photParams, seeing=lsstDefaults.seeing(f))
        fNorm = flatSed.calcFluxNorm(m5[f], system[f])
        flatSed.multiplyFluxNorm(fNorm)
        sourceCounts[f] = flatSed.calcADU(system[f], photParams=photParams)
        # Calculate the Skycounts expected in this bandpass.
        skyCounts[f] = darksky.calcADU(hardware[f], photParams=photParams) * photParams.platescale**2
        # Calculate the sky surface brightness.
        skyMag[f] = darksky.calcMag(hardware[f])
        # Calculate the gamma value.
        gamma[f] = SignalToNoise.calcGamma(system[f], m5[f], photParams)
    print title
    print 'Filter m5 SourceCounts SkyCounts SkyMag Gamma'
    for f in ('u', 'g' ,'r', 'i', 'z', 'y'):
        print '%s %.2f %.1f %.2f %.2f %.6f' %(f, m5[f], sourceCounts[f], skyCounts[f], skyMag[f], gamma[f])

    # Show what these look like individually (add sky & m5 limits on throughput curves)
    plt.figure()
    ax = plt.gca()
    # Add dark sky
    ax2 = ax.twinx()
    plt.sca(ax2)
    skyab = -2.5*np.log10(darksky.fnu) - darksky.zp
    ax2.plot(darksky.wavelen, skyab,
             'k-', linewidth=0.8, label='Dark sky mags')
    ax2.set_ylabel('AB mags')
    ax2.set_ylim(24, 10)
    plt.sca(ax)
    # end of dark sky
    handles = []
    for f in filterlist:
        plt.plot(system[f].wavelen, system[f].sb, color=filtercolors[f], linewidth=2)
        myline = mlines.Line2D([], [], color=filtercolors[f], linestyle='-', linewidth=2,
                               label = '%s: m5 %.1f (sky %.1f)' %(f, m5[f], skyMag[f]))
        handles.append(myline)
    plt.plot(atmos.wavelen, atmos.sb, 'k:', label='Atmosphere, X=1.2')
    # Add legend for dark sky.
    myline = mlines.Line2D([], [], color='k', linestyle='-', label='Dark sky AB mags')
    handles.append(myline)
    # end of dark sky legend line
    plt.legend(loc=(0.01, 0.69), handles=handles, fancybox=True, numpoints=1, fontsize='small')
    plt.ylim(0, 1)
    plt.xlim(300, 1100)
    plt.xlabel('Wavelength (nm)')
    plt.ylabel('Fractional Throughput Response')
    if title == 'Vendor combo':
        title = ''
    plt.title('System total response curves %s' %(title))
    if title == '':
        plt.savefig('throughputs.pdf', format='pdf', dpi=600)
    return m5
def calcM5(hardware, system, atmos, title='m5'):
    """
    Calculate m5 values for all filters in hardware and system.
    Prints all values that go into "table 2" of the overview paper.
    Returns dictionary of m5 values.
    """
    # photParams stores default values for the exposure time, nexp, size of the primary,
    #  readnoise, gain, platescale, etc.
    # See https://github.com/lsst/sims_photUtils/blob/master/python/lsst/sims/photUtils/PhotometricParameters.py
    photParams = PhotometricParameters(gain=1)
    photParams_infinity = PhotometricParameters(readnoise=0, darkcurrent=0,
                                                othernoise=0, gain=1)
    # lsstDefaults stores default values for the FWHMeff.
    # See https://github.com/lsst/sims_photUtils/blob/master/python/lsst/sims/photUtils/LSSTdefaults.py
    lsstDefaults = LSSTdefaults()
    darksky = Sed()
    darksky.readSED_flambda(os.path.join('../siteProperties', 'darksky.dat'))
    flatSed = Sed()
    flatSed.setFlatSED()
    m5 = {}
    Tb = {}
    Sb = {}
    kAtm = {}
    Cm = {}
    dCm_infinity = {}
    sourceCounts = {}
    skyCounts = {}
    skyMag = {}
    gamma = {}
    for f in system:
        m5[f] = SignalToNoise.calcM5(darksky, system[f], hardware[f], photParams,
                                     FWHMeff=lsstDefaults.FWHMeff(f))
        fNorm = flatSed.calcFluxNorm(m5[f], system[f])
        flatSed.multiplyFluxNorm(fNorm)
        sourceCounts[f] = flatSed.calcADU(system[f], photParams=photParams)
        # Calculate the Skycounts expected in this bandpass.
        skyCounts[f] = (darksky.calcADU(hardware[f], photParams=photParams)
                        * photParams.platescale**2)
        # Calculate the sky surface brightness.
        skyMag[f] = darksky.calcMag(hardware[f])
        # Calculate the gamma value.
        gamma[f] = SignalToNoise.calcGamma(system[f], m5[f], photParams)
        # Calculate the "Throughput Integral" (this is the hardware + atmosphere)
        dwavelen = np.mean(np.diff(system[f].wavelen))
        Tb[f] = np.sum(system[f].sb / system[f].wavelen) * dwavelen
        # Calculate the "Sigma" 'system integral' (this is the hardware only)
        Sb[f] = np.sum(hardware[f].sb / hardware[f].wavelen) * dwavelen
        # Calculate km - atmospheric extinction in a particular bandpass
        kAtm[f] = -2.5*np.log10(Tb[f] / Sb[f])
        # Calculate the Cm and Cm_Infinity values.
        # m5 = Cm + 0.5*(msky - 21) + 2.5log10(0.7/FWHMeff) + 1.25log10(t/30) - km(X-1.0)
        # Exptime should be 30 seconds and X=1.0
        exptime = photParams.exptime * photParams.nexp
        if exptime != 30.0:
            print "Whoa, exposure time was not as expected - got %s not 30 seconds. Please edit Cm calculation." %(exptime)
        # Assumes atmosphere used in system throughput is X=1.0
        X = 1.0
        Cm[f] = (m5[f] - 0.5*(skyMag[f] - 21) - 2.5*np.log10(0.7/lsstDefaults.FWHMeff(f)))
        # Calculate Cm_Infinity by setting readout noise to zero.
        m5inf = SignalToNoise.calcM5(darksky, system[f], hardware[f],  photParams_infinity,
                                     FWHMeff=lsstDefaults.FWHMeff(f))
        Cm_infinity = (m5inf - 0.5*(skyMag[f] - 21)
                       - 2.5*np.log10(0.7/lsstDefaults.FWHMeff(f)))
        dCm_infinity[f] = Cm_infinity - Cm[f]
    print title
    print 'Filter FWHMeff FWHMgeom SkyMag SkyCounts Tb Sb kAtm Gamma Cm dCm_infinity m5 SourceCounts'
    for f in ('u', 'g' ,'r', 'i', 'z', 'y'):
        print '%s %.2f %.2f %.2f %.1f %.3f %.3f %.4f %.6f %.2f %.2f %.2f %.2f'\
           %(f, lsstDefaults.FWHMeff(f),
             SignalToNoise.FWHMeff2FWHMgeom(lsstDefaults.FWHMeff(f)),
             skyMag[f], skyCounts[f], Tb[f], Sb[f], kAtm[f],
             gamma[f], Cm[f], dCm_infinity[f], m5[f], sourceCounts[f])

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

    plt.figure()
    ax = plt.gca()
    # Add dark sky
    ax2 = ax.twinx()
    plt.sca(ax2)
    skyab = -2.5*np.log10(darksky.fnu) - darksky.zp
    ax2.plot(darksky.wavelen, skyab,
             'k-', linewidth=0.8, label='Dark sky mags')
    ax2.set_ylabel('AB mags')
    ax2.set_ylim(24, 14)
    plt.sca(ax)
    # end of dark sky
    handles = []
    for f in filterlist:
        plt.plot(system[f].wavelen, system[f].sb, color=filtercolors[f], linewidth=2)
        myline = mlines.Line2D([], [], color=filtercolors[f], linestyle='-', linewidth=2,
                               label = '%s: m5 %.1f (sky %.1f)' %(f, m5[f], skyMag[f]))
        handles.append(myline)
    plt.plot(atmos.wavelen, atmos.sb, 'k:', label='Atmosphere, X=1.0')
    # Add legend for dark sky.
    myline = mlines.Line2D([], [], color='k', linestyle='-', label='Dark sky AB mags/arcsec^2')
    handles.append(myline)
    # end of dark sky legend line
    plt.legend(loc=(0.01, 0.69), handles=handles, fancybox=True, numpoints=1, fontsize='small')
    plt.ylim(0, 1)
    plt.xlim(300, 1100)
    plt.xlabel('Wavelength (nm)')
    plt.ylabel('Fractional Throughput Response')
    plt.title('System total response curves %s' %(title))
    return m5
                          wavelen_max=wavelen_max,
                          wavelen_step = wavelen_step)
    for f in filterlist:
        mags1[f][i] = tmpgal.calcMag(lsstbp[f])
dt, t = dtime(t)
print "Calculating dust/redshift/dust/fluxnorm/%d magnitudes for %d galaxies took %f s" \
      %(len(filterlist), num_gal, dt)

# For next test: want to also do all the same steps, but in an optimized form. This means
# doing some things that Sed does 'behind the scenes' explicitly, but also means the code may be a little
# harder to read at first.
# First: calculate internal a/b on wavelength range required for internal dust extinction.
a_int, b_int = gals[gallist[0]].setupCCMab()  # this is a/b on native galaxy sed range. 
# Next: calculate milky way a/b on wavelength range required for calculating magnitudes - i.e. 300 to 1200 nm.
tmpgal = Sed()
tmpgal.setFlatSED(wavelen_min=wavelen_min, wavelen_max=wavelen_max, wavelen_step = wavelen_step)
a_mw, b_mw = tmpgal.setupCCMab()  # so this is a/b on native MW bandpass range. 
# Also: set up phi for each bandpass - ahead of time. And set up a list of bandpasses, then create phiarray 
# and dlambda to set up for manyMagCalc method.
bplist = []
for f in filterlist:
    lsstbp[f].sbTophi()
    bplist.append(lsstbp[f])
phiarray, dlambda = tmpgal.setupPhiArray(bplist)
# Set up dictionary + arrays to hold calculated magnitude information. 
mags2 = {}
for f in filterlist:
    mags2[f] = numpy.zeros(num_gal, dtype='float')
# For each galaxy (in num_gal's), apply internal dust, redshift, resample to 300-1200 nm, apply MW dust on
#   shorter (and standardized) wavelength range, fluxnorm, and then calculate mags using manyMagCalc. 
for i in range(num_gal):