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)
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
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
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
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
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)
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)
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
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
def testVerboseSNR(self): """ Make sure that calcSNR_sed has everything it needs to run in verbose mode """ photParams = PhotometricParameters() # create a cartoon spectrum to test on spectrum = Sed() spectrum.setFlatSED() spectrum.multiplyFluxNorm(1.0e-9) snr.calcSNR_sed(spectrum, self.bpList[0], self.skySed, self.hardwareList[0], photParams, FWHMeff=0.7, verbose=True)
def 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
def testVerboseSNR(self): """ Make sure that calcSNR_sed has everything it needs to run in verbose mode """ defaults = LSSTdefaults() photParams = PhotometricParameters() #create a cartoon spectrum to test on spectrum = Sed() spectrum.setFlatSED() spectrum.multiplyFluxNorm(1.0e-9) snr.calcSNR_sed(spectrum, self.bpList[0], self.skySed, self.hardwareList[0], photParams, seeing=0.7, verbose=True)
def mag_to_flux_e_sec(self, mag, band, exptime, nexp): """ Mag to flux (in photoelec/sec) conversion Parameters -------------- mag : float input magnitudes band : str input bands exptime : float input exposure times nexp: int number of exposures Returns ---------- counts : float number of ADU counts e_per_sec : float flux in photoelectron per sec. """ if not hasattr(mag, '__iter__'): wavelen_min, wavelen_max, wavelen_step = self.atmosphere[ band].getWavelenLimits(None, None, None) sed = Sed() sed.setFlatSED() flux0 = sed.calcFluxNorm(mag, self.atmosphere[band]) sed.multiplyFluxNorm(flux0) photParams = PhotometricParameters(exptime=exptime, nexp=nexp) counts = sed.calcADU(bandpass=self.atmosphere[band], photParams=photParams) e_per_sec = counts # counts per sec e_per_sec /= (exptime * nexp) # conversion to pe e_per_sec *= photParams.gain return counts, e_per_sec else: r = [] for m, b, expt, nexpos in zip(mag, band, exptime, nexp): counts, flux_e = self.mag_to_flux_e_sec(m, b, expt, nexpos) r.append((counts, flux_e)) return np.asarray(r)
def ZP_filtre(self, filtre): """ ZP_filtre() : Compute zero point in filter band - platescale is 0.2 arcsec per pixel Tool function implemented by Phillie Gris (IN2P3) """ # extract parameters from lsst_sims photParams = PhotometricParameters(bandpass=filtre) # compute Diameter in meters : D=2*R = 2*sqrt(S/pi) Diameter = 2. * np.sqrt( photParams.effarea * 1.e-4 / np.pi) # diameter in meter # AB flux is 3.6307805477e-20 erg/cm2/s/Hz or 3.6307805477e-16 erg/m2/s/Hz # or 3.6307e-23 J/m2/s/Hz, h=6.626e-34 J.s # What is the meaning of this Cte ???? # especcialy what is 1e36 ? Cte = 3631. * np.pi * Diameter**2 * 2. * photParams.exptime / 4 / h / 1.e36 #print('Telescope::ZP_filtre: hello Cte=',Cte, ' Diam=',Diameter, 'h=',h,' exptime=',photParams.exptime) # What is the meaning of Skyb ????? self.data['Skyb'][filtre] = Cte * np.power( Diameter / 6.5, 2.) * np.power( 2. * photParams.exptime / 30., 2.) * np.power( photParams.platescale, 2.) * np.power( 10., 0.4 * (25. - self.mag_sky[filtre])) * self.Sigmab[filtre] #What is the meaning of Sigmab, Tb, Zb such Zb is used to calculate zero point Zb = 181.8 * np.power(Diameter / 6.5, 2.) * self.Tb[filtre] mbZ = 25. + 2.5 * np.log10(Zb) #filter without atmosphere filtre_trans = self.system[filtre] wavelen_min, wavelen_max, wavelen_step = filtre_trans.getWavelenLimits( None, None, None) bandpass = Bandpass(wavelen=filtre_trans.wavelen, sb=filtre_trans.sb) flatSed = Sed() flatSed.setFlatSED(wavelen_min, wavelen_max, wavelen_step) flux0 = np.power(10., -0.4 * mbZ) flatSed.multiplyFluxNorm(flux0) photParams = PhotometricParameters(bandpass=filtre) counts = flatSed.calcADU( bandpass, photParams=photParams) #number of counts for exptime self.data['zp'][filtre] = mbZ #print('Telescope::ZP_filtre hello',counts/self.photParams.exptime) self.data['counts_zp'][filtre] = counts / 2. * photParams.exptime
def 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'])
def Calc_m5(self, filtre): """ Calc_m5(filtre): Compute m5 or SNR at five sigma Tool function implemented by Phillie Gris (IN2P3) """ # get telescope passband (no atmosphere) filtre_trans = self.system[filtre] wavelen_min, wavelen_max, wavelen_step = filtre_trans.getWavelenLimits( None, None, None) bandpass = Bandpass(wavelen=filtre_trans.wavelen, sb=filtre_trans.sb) # create a Flat sed S_nu from the sky brightness magnitude flatSedb = Sed() flatSedb.setFlatSED(wavelen_min, wavelen_max, wavelen_step) flux0b = np.power(10., -0.4 * self.mag_sky[filtre]) flatSedb.multiplyFluxNorm(flux0b) # Get LSST photometric parameters photParams = PhotometricParameters(bandpass=filtre) norm = photParams.platescale**2 / 2. * photParams.exptime / photParams.gain # Use LSST sims (SignalToNoise) to calculate M5 with atmosphere or without atmosphere if self.atmos: self.data['m5'][filtre] = SignalToNoise.calcM5( flatSedb, self.atmosphere[filtre], self.system[filtre], photParams=photParams, FWHMeff=self.FWHMeff[filtre]) adu_int = flatSedb.calcADU(bandpass=self.atmosphere[filtre], photParams=photParams) self.data['flux_sky'][filtre] = adu_int * norm else: self.data['m5'][filtre] = SignalToNoise.calcM5( flatSedb, self.system[filtre], self.system[filtre], photParams=photParams, FWHMeff=self.FWHMeff[filtre]) adu_int = flatSedb.calcADU(bandpass=self.system[filtre], photParams=photParams) self.data['flux_sky'][filtre] = adu_int * norm
def testMagError(self): """ Make sure that calcMagError_sed and calcMagError_m5 agree to within 0.001 """ defaults = LSSTdefaults() photParams = PhotometricParameters() # create a cartoon spectrum to test on spectrum = Sed() spectrum.setFlatSED() spectrum.multiplyFluxNorm(1.0e-9) # find the magnitudes of that spectrum in our bandpasses magList = [] for total in self.bpList: magList.append(spectrum.calcMag(total)) magList = np.array(magList) # try for different normalizations of the skySED for fNorm in np.arange(1.0, 5.0, 1.0): self.skySed.multiplyFluxNorm(fNorm) for total, hardware, filterName, mm in \ zip(self.bpList, self.hardwareList, self.filterNameList, magList): FWHMeff = defaults.FWHMeff(filterName) m5 = snr.calcM5(self.skySed, total, hardware, photParams, FWHMeff=FWHMeff) sigma_sed = snr.calcMagError_sed(spectrum, total, self.skySed, hardware, photParams, FWHMeff=FWHMeff) sigma_m5, gamma = snr.calcMagError_m5(mm, total, m5, photParams) self.assertAlmostEqual(sigma_m5, sigma_sed, 3)
def CalcMyABMagnitudesError_filter(self, band, SkyBrightnessMag, FWHMGeom): """ CalcMyABMagnitudesError_filter(self,band,SkyBrightnessMag,FWHMGeom) - author : Sylvie Dagoret-Campagne - affiliation : LAL/IN2P3/CNRS/FRANCE - date : July 5th 2018 Calculate magnitude errors for one band. Input args: - band : filter band - SkyBrighnessMag : Sky Brighness Magnitude in the band - FWHMGeom : Geometrical PSF in the band """ filtre_atm = self.lsst_atmos[band] filtre_syst = self.lsst_system[band] wavelen_min, wavelen_max, wavelen_step = filtre_syst.getWavelenLimits( None, None, None) #calculation of effective PSF FWHMeff = SignalToNoise.FWHMgeom2FWHMeff(FWHMGeom) photParams = PhotometricParameters(bandpass=band) # create a Flat sed S_nu from the sky brightness magnitude skysed = Sed() skysed.setFlatSED(wavelen_min, wavelen_max, wavelen_step) flux0b = np.power(10., -0.4 * SkyBrightnessMag) skysed.multiplyFluxNorm(flux0b) #calcMagError filled according doc mag_err = SignalToNoise.calcMagError_sed(self.sed, filtre_atm, skysed, filtre_syst, photParams, FWHMeff, verbose=False) return mag_err
def 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 get_zp(self, what, band): """ decorator get zero points formula used here are extracted from LSE-40 Parameters --------------- what: str parameter to estimate band: str filter """ photParams = PhotometricParameters(bandpass=band) Diameter = 2. * np.sqrt( photParams.effarea * 1.e-4 / np.pi) # diameter in meter Cte = 3631. * np.pi * Diameter**2 * 2. * photParams.exptime / 4 / h / 1.e36 self.data['Skyb'][band] = Cte*np.power(Diameter/6.5, 2.)\ * np.power(2.*photParams.exptime/30., 2.)\ * np.power(photParams.platescale, 2.)\ * 10.**0.4*(25.-self.mag_sky(band))\ * self.Sigmab(band) Zb = 181.8 * np.power(Diameter / 6.5, 2.) * self.Tb(band) mbZ = 25. + 2.5 * np.log10(Zb) filtre_trans = self.system[band] wavelen_min, wavelen_max, wavelen_step = filtre_trans.getWavelenLimits( None, None, None) bandpass = Bandpass(wavelen=filtre_trans.wavelen, sb=filtre_trans.sb) flatSed = Sed() flatSed.setFlatSED(wavelen_min, wavelen_max, wavelen_step) flux0 = np.power(10., -0.4 * mbZ) flatSed.multiplyFluxNorm(flux0) photParams = PhotometricParameters(bandpass=band) # number of counts for exptime counts = flatSed.calcADU(bandpass, photParams=photParams) self.data['zp'][band] = mbZ self.data['counts_zp'][band] = counts / 2. * photParams.exptime
def Calc_m5(self, filtre): filtre_trans = self.throughputs.system[filtre] wavelen_min, wavelen_max, wavelen_step = filtre_trans.getWavelenLimits( None, None, None) bandpass = Bandpass(wavelen=filtre_trans.wavelen, sb=filtre_trans.sb) flatSedb = Sed() flatSedb.setFlatSED(wavelen_min, wavelen_max, wavelen_step) flux0b = np.power(10., -0.4 * self.mag_sky[filtre]) flatSedb.multiplyFluxNorm(flux0b) if self.atmos: self.data['m5'][filtre] = SignalToNoise.calcM5( flatSedb, self.throughputs.atmosphere[filtre], self.throughputs.system[filtre], photParams=self.photParams, FWHMeff=self.FWHMeff[filtre]) adu_int = flatSedb.calcADU( bandpass=self.throughputs.atmosphere[filtre], photParams=self.photParams) self.data['flux_sky'][ filtre] = adu_int * self.pixel_area / self.expTime[ filtre] / self.gain else: self.data['m5'][filtre] = SignalToNoise.calcM5( flatSedb, self.throughputs.system[filtre], self.throughputs.system[filtre], photParams=self.photParams, FWHMeff=self.FWHMeff[filtre]) adu_int = flatSedb.calcADU( bandpass=self.throughputs.system[filtre], photParams=self.photParams) self.data['flux_sky'][ filtre] = adu_int * self.pixel_area / self.expTime[ filtre] / self.gain
def __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)
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)
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)
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
def CalcMyABMagnitudesErrors(self): """ CalcMyABMagnitudesErrors(self) - author : Sylvie Dagoret-Campagne - affiliation : LAL/IN2P3/CNRS/FRANCE - date : July 4th 2018 Calculate magnitude errors for all bands """ all_magABErr = [] for i, band in enumerate(self.filterlist): filtre_atm = self.lsst_atmos[band] filtre_syst = self.lsst_system[band] wavelen_min, wavelen_max, wavelen_step = filtre_syst.getWavelenLimits( None, None, None) photParams = PhotometricParameters(bandpass=band) FWHMeff = self.data['FWHMeff'][band] # create a Flat sed S_nu from the sky brightness magnitude skysed = Sed() skysed.setFlatSED(wavelen_min, wavelen_max, wavelen_step) flux0b = np.power(10., -0.4 * self.mag_sky[band]) skysed.multiplyFluxNorm(flux0b) #calcMagError filled according doc magerr=SignalToNoise.calcMagError_sed( \ self.sed,filtre_atm,skysed,filtre_syst,photParams,FWHMeff,verbose=False) all_magABErr.append(magerr) return np.array(all_magABErr)
def 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
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.
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
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 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
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
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
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
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):