def loadwdSEDs(self, subset = None): """ By default will load all seds in wd directory. The user can also define a subset of what's in the directory and load only those SEDs instead. Will skip over extraneous files in sed folder. @param [in] subset is the list of the subset of files wanted if one doesn't want all files in the kurucz directory. @param [out] sedListH is the set of model SED spectra objects for Hydrogen WDs to be passed onto the matching routines. @param [out] sedListHE is the set of model SED spectra objects for Helium WDs to be passed onto the matching routines. """ if self.wdDir is None: try: self.wdDir = str(self.sEDDir + '/' + self.specMapDict['wd'] + '/') except: raise ValueError(str('self.wdDir is None. ' + 'Add path to wddirectory.')) files = [] if subset is None: for fileName in os.listdir(self.wdDir): files.append(fileName) else: for fileName in subset: files.append(fileName) numFiles = len(files) numOn = 0 sedListH = [] sedListHE = [] for fileName in files: if numOn % 100 == 0: print('Loading %i of %i: WD SEDs' % (numOn, numFiles)) try: spec = Sed() spec.readSED_flambda(str(self.wdDir + '/' + fileName)) spec.name = fileName if fileName.split("_")[1] == 'He': sedListHE.append(spec) else: sedListH.append(spec) except: continue numOn += 1 return sedListH, sedListHE
def _fluxes(sed_name, mag_norm, redshift): """ Find the fluxes for a galaxy component Parameters ---------- sed_name is an SED file name mag_norm is a float redshift is a float Returns ------- array of fluxes in ugrizy order """ if not hasattr(_fluxes, '_bp_dict'): bp_dir = getPackageDir('throughputs') bp_dir = os.path.join(bp_dir, 'imsim', 'goal') _fluxes._bp_dict = BandpassDict.loadTotalBandpassesFromFiles( bandpassDir=bp_dir) _fluxes._sed_dir = getPackageDir('sims_sed_library') spec = Sed() full_sed_name = os.path.join(_fluxes._sed_dir, sed_name) if not os.path.isfile(full_sed_name): full_sed_name = os.path.join(_fluxes._sed_dir, defaultSpecMap[sed_name]) spec.readSED_flambda(full_sed_name) fnorm = getImsimFluxNorm(spec, mag_norm) spec.multiplyFluxNorm(fnorm) spec.redshiftSED(redshift, dimming=True) return _fluxes._bp_dict.fluxListForSed(spec)
def _calcColors(self, sedname='C.dat'): """ Calculate the colors for a moving object with sed 'sedname'. """ # Do we need to read in the LSST bandpasses? try: self.lsst except AttributeError: filterdir = os.getenv('LSST_THROUGHPUTS_BASELINE') filterlist = ('u', 'g', 'r', 'i', 'z', 'y') self.lsst ={} for f in filterlist: self.lsst[f] = Bandpass() self.lsst[f].readThroughput(os.path.join(filterdir, 'total_'+f+'.dat')) self.vband = Bandpass() self.vband.readThroughput('harris_V.dat') self.colors = {} # See if the sed's colors are in memory already. if sedname not in self.colors: moSed = Sed() moSed.readSED_flambda(sedname) vmag = moSed.calcMag(self.vband) self.colors[sedname] = {} for f in filterlist: self.colors[sedname][f] = moSed.calcMag(self.lsst[f]) - vmag return self.colors[sedname]
def calcColors(self, sedname='C.dat', sedDir=None): """Calculate the colors for a given SED. If the sedname is not already in the dictionary self.colors, this reads the SED from disk and calculates all V-[filter] colors for all filters in self.filterlist. The result is stored in self.colors[sedname][filter]. Parameters ---------- sedname : str (opt) Name of the SED. Default 'C.dat'. sedDir : str (opt) Directory containing the SEDs of the moving objects. Default None = $SIMS_MOVINGOBJECTS_DIR/data. Returns ------- dict Dictionary of the colors in self.filterlist for this particular Sed. """ if sedname not in self.colors: if sedDir is None: sedDir = os.path.join(getPackageDir('SIMS_MOVINGOBJECTS'), 'data') moSed = Sed() moSed.readSED_flambda(os.path.join(sedDir, sedname)) vmag = moSed.calcMag(self.vband) self.colors[sedname] = {} for f in self.filterlist: self.colors[sedname][f] = moSed.calcMag(self.lsst[f]) - vmag return self.colors[sedname]
def _getSedCopy(self, sedName): """ Return a copy of the requested SED, either from the cached version or creating a new one and caching a copy for later reuse. """ if sedName in self.uniqueSeds: # we have already read in this file; no need to do it again sed = Sed(wavelen=self.uniqueSeds[sedName].wavelen, flambda=self.uniqueSeds[sedName].flambda, fnu=self.uniqueSeds[sedName].fnu, name=self.uniqueSeds[sedName].name) else: # load the SED of the object sed = Sed() sedFile = os.path.join(self.sedDir, sedName) sed.readSED_flambda(sedFile) flambdaCopy = copy.deepcopy(sed.flambda) #If the SED is zero inside of the bandpass, GalSim raises an error. #This sets a minimum flux value of 1.0e-30 so that the SED is never technically #zero inside of the bandpass. sed.flambda = numpy.array([ff if ff>1.0e-30 else 1.0e-30 for ff in flambdaCopy]) sed.fnu = None #copy the unnormalized file to uniqueSeds so we don't have to read it in again sedCopy = Sed(wavelen=sed.wavelen, flambda=sed.flambda, fnu=sed.fnu, name=sed.name) self.uniqueSeds[sedName] = sedCopy return sed
def get_sed(name, magnorm, redshift, av, rv): if not hasattr(get_sed, '_rest_dict'): get_sed._rest_dict = {} get_sed._imsim_bp = Bandpass() get_sed._imsim_bp.imsimBandpass() get_sed._sed_dir = os.environ['SIMS_SED_LIBRARY_DIR'] get_sed._ccm_w = None tag = '%s_%.2f_%.2f' % (name, av, rv) if tag not in get_sed._rest_dict: ss = Sed() ss.readSED_flambda(os.path.join(get_sed._sed_dir, name)) if get_sed._ccm_w is None or not np.array_equal( ss.wavelen, get_sed._ccm_w): get_sed._ccm_w = np.copy(ss.wavelen) get_sed._ax, get_sed._bx = ss.setupCCM_ab() mn = ss.calcMag(get_sed._imsim_bp) ss.addDust(get_sed._ax, get_sed._bx, A_v=av, R_v=rv) get_sed._rest_dict[tag] = (ss, mn) base_sed = get_sed._rest_dict[tag][0] ss = Sed(wavelen=base_sed.wavelen, flambda=base_sed.flambda) dmag = magnorm - get_sed._rest_dict[tag][1] fnorm = np.power(10.0, -0.4 * dmag) ss.multiplyFluxNorm(fnorm) ss.redshiftSED(redshift, dimming=True) return ss
def testNoSystematicUncertainty(self): """ Test that systematic uncertainty is handled correctly when set to None. """ m5 = [23.5, 24.3, 22.1, 20.0, 19.5, 21.7] photParams = PhotometricParameters(sigmaSys=0.0) obs_metadata = ObservationMetaData( unrefractedRA=23.0, unrefractedDec=45.0, m5=m5, bandpassName=self.filterNameList ) magnitudes = [] for bp in self.bpList: mag = self.starSED.calcMag(bp) magnitudes.append(mag) skySedList = [] for bp, hardware, filterName in zip(self.bpList, self.hardwareList, self.filterNameList): skyDummy = Sed() skyDummy.readSED_flambda(os.path.join(lsst.utils.getPackageDir("throughputs"), "baseline", "darksky.dat")) normalizedSkyDummy = setM5( obs_metadata.m5[filterName], skyDummy, bp, hardware, seeing=LSSTdefaults().seeing(filterName), photParams=photParams, ) skySedList.append(normalizedSkyDummy) sigmaList = snr.calcMagError_m5(numpy.array(magnitudes), numpy.array(self.bpList), numpy.array(m5), photParams) for i in range(len(self.bpList)): snrat = snr.calcSNR_sed( self.starSED, self.bpList[i], skySedList[i], self.hardwareList[i], seeing=LSSTdefaults().seeing(self.filterNameList[i]), photParams=PhotometricParameters(), ) testSNR, gamma = snr.calcSNR_m5( numpy.array([magnitudes[i]]), [self.bpList[i]], numpy.array([m5[i]]), photParams=PhotometricParameters(sigmaSys=0.0), ) self.assertAlmostEqual( snrat, testSNR[0], 10, msg="failed on calcSNR_m5 test %e != %e " % (snrat, testSNR[0]) ) control = snr.magErrorFromSNR(testSNR) msg = "%e is not %e; failed" % (sigmaList[i], control) self.assertAlmostEqual(sigmaList[i], control, 10, msg=msg)
def calculate_mags(sed_name, mag_norm, out_dict): """ Parameters ---------- sed_name is a numpy array of SED names mag_norm is a numpy array of magNorms out_dict is a multiprocessing.Manager.dict() that will store the magnitudes calculated by this process. """ i_process = mp.current_process().pid bp_dir = getPackageDir('throughputs') bp_dir = os.path.join(bp_dir, 'imsim', 'goal') bp_dict = BandpassDict.loadTotalBandpassesFromFiles(bandpassDir=bp_dir) sed_dir = getPackageDir('sims_sed_library') out_mags = np.zeros((len(sed_name), 6), dtype=float) for i_star, (s_name, m_norm) in enumerate(zip(sed_name, mag_norm)): spec = Sed() spec.readSED_flambda(os.path.join(sed_dir, defaultSpecMap[s_name])) fnorm = getImsimFluxNorm(spec, m_norm) spec.multiplyFluxNorm(fnorm) mags = bp_dict.magListForSed(spec) out_mags[i_star] = mags out_dict[i_process] = out_mags
def _getSedCopy(self, sedName): """ Return a copy of the requested SED, either from the cached version or creating a new one and caching a copy for later reuse. """ if sedName in self.uniqueSeds: # we have already read in this file; no need to do it again sed = Sed(wavelen=self.uniqueSeds[sedName].wavelen, flambda=self.uniqueSeds[sedName].flambda, fnu=self.uniqueSeds[sedName].fnu, name=self.uniqueSeds[sedName].name) else: # load the SED of the object sed = Sed() sedFile = os.path.join(self.sedDir, sedName) sed.readSED_flambda(sedFile) flambdaCopy = copy.deepcopy(sed.flambda) # If the SED is zero inside of the bandpass, GalSim raises an error. # This sets a minimum flux value of 1.0e-30 so that the SED is never technically # zero inside of the bandpass. sed.flambda = np.array([ff if ff > 1.0e-30 else 1.0e-30 for ff in flambdaCopy]) sed.fnu = None # copy the unnormalized file to uniqueSeds so we don't have to read it in again sedCopy = Sed(wavelen=sed.wavelen, flambda=sed.flambda, fnu=sed.fnu, name=sed.name) self.uniqueSeds[sedName] = sedCopy return sed
def testStellarPhotometricUncertainties(self): """ Test in the case of a catalog of stars """ lsstDefaults = LSSTdefaults() starDB = testStarsDBObj(driver=self.driver, host=self.host, database=self.dbName) starCat = testStarCatalog(starDB, obs_metadata=self.obs_metadata) phot = PhotometryStars() ct = 0 for line in starCat.iter_catalog(): starSed = Sed() starSed.readSED_flambda(os.path.join(lsst.utils.getPackageDir('sims_sed_library'), defaultSpecMap[line[14]])) imsimband = Bandpass() imsimband.imsimBandpass() fNorm = starSed.calcFluxNorm(line[15], imsimband) starSed.multiplyFluxNorm(fNorm) aV = numpy.float(line[16]) a_int, b_int = starSed.setupCCMab() starSed.addCCMDust(a_int, b_int, A_v=aV) for i in range(len(self.bandpasses)): controlSigma = calcMagError_sed(starSed, self.totalBandpasses[i], self.skySeds[i], self.hardwareBandpasses[i], FWHMeff=lsstDefaults.FWHMeff(self.bandpasses[i]), photParams=PhotometricParameters()) testSigma = line[8+i] self.assertAlmostEqual(controlSigma, testSigma, 4) ct += 1 self.assertGreater(ct, 0)
def _create_library_one_sed(_galaxy_sed_dir, sed_file_name_list, av_grid, rv_grid, bandpass_dict, out_dict, out_lock): n_obj = 0 for i_av, av in enumerate(av_grid): for i_rv, rv in enumerate(rv_grid): if av < 0.01 and i_rv > 0: continue n_obj += 1 imsim_bp = Bandpass() imsim_bp.imsimBandpass() t_start = time.time() sed_names_out = [] rv_out_list_out = [] av_out_list_out = [] sed_mag_norm_out = [] sed_mag_list_out = [] for i_sed, sed_file_name in enumerate(sed_file_name_list): base_spec = Sed() base_spec.readSED_flambda(os.path.join(_galaxy_sed_dir, sed_file_name)) ax, bx = base_spec.setupCCM_ab() mag_norm = base_spec.calcMag(imsim_bp) sed_names = np.array([defaultSpecMap[sed_file_name]] * n_obj) rv_out_list = np.zeros(n_obj, dtype=float) av_out_list = np.zeros(n_obj, dtype=float) sed_mag_norm = mag_norm * np.ones(n_obj, dtype=float) sed_mag_list = np.zeros((n_obj, len(bandpass_dict)), dtype=float) i_obj = 0 for i_av, av in enumerate(av_grid): for i_rv, rv in enumerate(rv_grid): if av < 0.01 and i_rv > 0: continue spec = Sed(wavelen=base_spec.wavelen, flambda=base_spec.flambda) spec.addDust(ax, bx, A_v=av, R_v=rv) av_out_list[i_obj] = av rv_out_list[i_obj] = rv sed_mag_list[i_obj][:] = bandpass_dict.magListForSed(spec) i_obj += 1 sed_names_out.append(sed_names) sed_mag_norm_out.append(sed_mag_norm) sed_mag_list_out.append(sed_mag_list) av_out_list_out.append(av_out_list) rv_out_list_out.append(rv_out_list) with out_lock: out_dict['sed_names'] += sed_names_out out_dict['sed_mag_norm'] += sed_mag_norm_out out_dict['sed_mag_list'] += sed_mag_list_out out_dict['av_out_list'] += av_out_list_out out_dict['rv_out_list'] += rv_out_list_out
def loadwdSEDs(self, subset=None): """ By default will load all seds in wd directory. The user can also define a subset of what's in the directory and load only those SEDs instead. Will skip over extraneous files in sed folder. @param [in] subset is the list of the subset of files wanted if one doesn't want all files in the kurucz directory. @param [out] sedListH is the set of model SED spectra objects for Hydrogen WDs to be passed onto the matching routines. @param [out] sedListHE is the set of model SED spectra objects for Helium WDs to be passed onto the matching routines. """ if self.wdDir is None: try: self.wdDir = str(self.sEDDir + '/' + self.specMapDict['wd'] + '/') except: raise ValueError( str('self.wdDir is None. ' + 'Add path to wddirectory.')) files = [] if subset is None: for fileName in os.listdir(self.wdDir): files.append(fileName) else: for fileName in subset: files.append(fileName) numFiles = len(files) numOn = 0 sedListH = [] sedListHE = [] for fileName in files: if numOn % 100 == 0: print('Loading %i of %i: WD SEDs' % (numOn, numFiles)) try: spec = Sed() spec.readSED_flambda(str(self.wdDir + '/' + fileName)) spec.name = fileName if fileName.split("_")[1] == 'He': sedListHE.append(spec) else: sedListH.append(spec) except: continue numOn += 1 return sedListH, sedListHE
def testSystematicUncertainty(self): """ Test that systematic uncertainty is added correctly. """ sigmaSys = 0.002 m5_list = [23.5, 24.3, 22.1, 20.0, 19.5, 21.7] photParams = PhotometricParameters(sigmaSys=sigmaSys) obs_metadata = ObservationMetaData(pointingRA=23.0, pointingDec=45.0, m5=m5_list, bandpassName=self.filterNameList) magnitude_list = [] for bp in self.bpList: mag = self.starSED.calcMag(bp) magnitude_list.append(mag) for bp, hardware, filterName, mm, m5 in \ zip(self.bpList, self.hardwareList, self.filterNameList, magnitude_list, m5_list): skyDummy = Sed() skyDummy.readSED_flambda( os.path.join(lsst.utils.getPackageDir('throughputs'), 'baseline', 'darksky.dat')) normalizedSkyDummy = setM5( obs_metadata.m5[filterName], skyDummy, bp, hardware, FWHMeff=LSSTdefaults().FWHMeff(filterName), photParams=photParams) sigma, gamma = snr.calcMagError_m5(mm, bp, m5, photParams) snrat = snr.calcSNR_sed(self.starSED, bp, normalizedSkyDummy, hardware, FWHMeff=LSSTdefaults().FWHMeff(filterName), photParams=PhotometricParameters()) testSNR, gamma = snr.calcSNR_m5( mm, bp, m5, photParams=PhotometricParameters(sigmaSys=0.0)) self.assertAlmostEqual(snrat, testSNR, 10, msg='failed on calcSNR_m5 test %e != %e ' % (snrat, testSNR)) control = np.sqrt( np.power(snr.magErrorFromSNR(testSNR), 2) + np.power(sigmaSys, 2)) msg = '%e is not %e; failed' % (sigma, control) self.assertAlmostEqual(sigma, control, 10, msg=msg)
def _get_sed_mags_and_cosmology(catalog_name): """ Returns 3 numpy arrays: sed_names, sed_mag_list, sed_mag_norm and a dictionary for cosmology sed_names is 1d str array, with length = number of SED files in the library sed_mag_list is MxN float array, with M = number of SED files in the library, and N = number of top hat filters in the catalog sed_mag_norm is 1d float array, with length = number of SED files in the library cosmology = {'H0': H0, 'Om0': Om0} """ gc = GCRCatalogs.load_catalog(catalog_name, config_overwrite=dict(md5=False)) cosmo = dict(H0=gc.cosmology.H0.value, Om0=gc.cosmology.Om0) bp_params_raw = {'disk': set(), 'bulge': set()} for q in gc.list_all_quantities(): m = _gcr_sed_re.match(q) if m: wav0, width, tag = m.groups() bp_params_raw[tag].add((int(wav0), int(width))) assert bp_params_raw['disk'] == bp_params_raw[ 'bulge'], 'SEDs for disk and bulge do not match' assert bp_params_raw['disk'], 'No SED found' bp_params_sorted = sorted(bp_params_raw['disk'], key=lambda p: p[0]) # SED labels in GCR specify the band pass in angstrom, but CatSim uses nm # Hence the conversion factor 0.1 in the code below wav_min = bp_params_sorted[0][0] * 0.1 wav_max = max((0.1 * (wav0 + width) for wav0, width in bp_params_sorted)) wav_grid = np.arange(wav_min, wav_max, 0.1) bp_name_list = list() bp_list = list() for wav0, width in bp_params_sorted: sb_grid = ((wav_grid >= wav0 * 0.1) & (wav_grid <= (wav0 + width) * 0.1)).astype(float) bp_list.append(Bandpass(wavelen=wav_grid, sb=sb_grid)) bp_name_list.append('%d_%d' % (wav0, width)) bandpass_dict = BandpassDict(bp_list, bp_name_list) sed_names = list() sed_mag_list = list() sed_mag_norm = list() imsim_bp = Bandpass() imsim_bp.imsimBandpass() for sed_file_name in os.listdir(_galaxy_sed_dir): spec = Sed() spec.readSED_flambda(os.path.join(_galaxy_sed_dir, sed_file_name)) sed_names.append(sed_file_name) sed_mag_list.append(tuple(bandpass_dict.magListForSed(spec))) sed_mag_norm.append(spec.calcMag(imsim_bp)) return np.array(sed_names), np.array(sed_mag_list), np.array( sed_mag_norm), cosmo
def testSignalToNoise(self): """ Test that calcSNR_m5 and calcSNR_sed give similar results """ defaults = LSSTdefaults() photParams = PhotometricParameters() m5 = [] for i in range(len(self.hardwareList)): m5.append( snr.calcM5( self.skySed, self.bpList[i], self.hardwareList[i], photParams, seeing=defaults.seeing(self.filterNameList[i]), ) ) sedDir = lsst.utils.getPackageDir("sims_sed_library") sedDir = os.path.join(sedDir, "starSED", "kurucz") fileNameList = os.listdir(sedDir) numpy.random.seed(42) offset = numpy.random.random_sample(len(fileNameList)) * 2.0 for ix, name in enumerate(fileNameList): if ix > 100: break spectrum = Sed() spectrum.readSED_flambda(os.path.join(sedDir, name)) ff = spectrum.calcFluxNorm(m5[2] - offset[ix], self.bpList[2]) spectrum.multiplyFluxNorm(ff) magList = [] controlList = [] magList = [] for i in range(len(self.bpList)): controlList.append( snr.calcSNR_sed( spectrum, self.bpList[i], self.skySed, self.hardwareList[i], photParams, defaults.seeing(self.filterNameList[i]), ) ) magList.append(spectrum.calcMag(self.bpList[i])) testList, gammaList = snr.calcSNR_m5( numpy.array(magList), numpy.array(self.bpList), numpy.array(m5), photParams ) for tt, cc in zip(controlList, testList): msg = "%e != %e " % (tt, cc) self.assertTrue(numpy.abs(tt / cc - 1.0) < 0.001, msg=msg)
def _parallel_fitting(mag_array, redshift, redshift_true, H0, Om0, wav_min, wav_width, lsst_mag_array, out_dict, tag): pid = os.getpid() (sed_names, mag_norms, av_arr, rv_arr) = sed_from_galacticus_mags(mag_array, redshift, redshift_true, H0, Om0, wav_min, wav_width, lsst_mag_array) tot_bp_dict = BandpassDict.loadTotalBandpassesFromFiles() sed_dir = getPackageDir('sims_sed_library') lsst_fit_fluxes = np.zeros((6, len(sed_names)), dtype=float) t_start = time.time() ccm_w = None restframe_seds = {} imsim_bp = Bandpass() imsim_bp.imsimBandpass() n04_ln10 = -0.4 * np.log(10) for ii in range(len(sed_names)): av_val = av_arr[ii] rv_val = rv_arr[ii] sed_tag = '%s_%.3f_%.3f' % (sed_names[ii], av_val, rv_val) if sed_tag not in restframe_seds: rest_sed = Sed() rest_sed.readSED_flambda(os.path.join(sed_dir, sed_names[ii])) mag = rest_sed.calcMag(imsim_bp) if ccm_w is None or not np.array_equal(rest_sed.wavelen, ccm_w): ccm_w = np.copy(rest_sed.wavelen) ax, bx = rest_sed.setupCCM_ab() rest_sed.addDust(ax, bx, A_v=av_val, R_v=rv_val) restframe_seds[sed_tag] = (rest_sed, mag) for i_bp, bp in enumerate('ugrizy'): m_norm = mag_norms[i_bp][ii] if m_norm > 0.0 and not np.isfinite(m_norm): continue spec = Sed(wavelen=restframe_seds[sed_tag][0].wavelen, flambda=restframe_seds[sed_tag][0].flambda) fnorm = np.exp(n04_ln10 * (m_norm - restframe_seds[sed_tag][1])) try: assert np.isfinite(fnorm) assert fnorm > 0.0 except AssertionError: print('\n\nmagnorm %e\n\n' % (m_norm)) raise spec.multiplyFluxNorm(fnorm) spec.redshiftSED(redshift[ii], dimming=True) ff = spec.calcFlux(tot_bp_dict[bp]) lsst_fit_fluxes[i_bp][ii] = ff out_dict[tag] = (sed_names, mag_norms, av_arr, rv_arr, lsst_fit_fluxes)
def quasarMag(z, M1450, survey, f): if (z, M1450, survey, f) in magCache: return magCache[(z, M1450, survey, f)] # for files containing $\lambda$ / F$_\lambda$, we use the Sed method # readSED_flambda. For files containing $\lambda$ / F$_\nu$, # we would use the readSED_fnu method instead. # get the path to the SED file for this z sedFilename = config.sedFilenameFormat.format(config.reddening, z) spectrumFilename = os.path.join(config.sedDir, sedFilename) # Read the spectrum. agn = Sed() agn.readSED_flambda(spectrumFilename) # Suppose you had a spectrum, but it didn't have an absolute scale. Or you # wanted to scale it to have a given magnitude in a particular bandpass. # For example, say we wanted to make our 'agn' spectrum have an r band # magnitude of 20, then calculate the magnitudes in all bandpasses. We # just use the calcFluxNorm and multiplyFluxNorm methods. # Scale spectrum and recalculate magnitudes. # given an absolute M1450, the observed magnitude m corresponding # to rest-frame 145nm radiation is # m = M1450+5log(d_L/10pc) - 2.5log(1+z) # so let's calculate m and then normalize our spectrum to that # first we need d_L = (1+z) * comoving distance # comoving distance is D_hubble * int_0^z dz'/sqrt(omegaM(1+z)^3+omegaLambda) def E(zp): return np.sqrt(config.omegaM * (1 + zp)**3 + config.omegaLambda) DC = config.DH * integrate.quad(lambda zp: 1 / E(zp), 0, z)[0] DL = (1 + z) * DC DL = DL * config.m2pc m = M1450 + 5 * np.log10(DL / 10) - 2.5 * np.log10(1 + z) # make a square bandpass at 145nm (in the quasar rest frame) # with a width of 1nm wavelen = np.arange(300, 2000, 0.1) sb = np.zeros(wavelen.shape) id1450 = int(((145 * (1 + z)) - 300) / 0.1) sb[id1450 - 5:id1450 + 5] = 1 band1450 = Bandpass(wavelen=wavelen, sb=sb) # normalize the sed to m at the (rest-frame) 1450A bandpass fluxNorm = agn.calcFluxNorm(m, band1450) agn.multiplyFluxNorm(fluxNorm) # Calculate expected AB magnitudes in the requested lsst band bandpass = f2Throughput(survey, f) mag = agn.calcMag(bandpass) magCache[(z, M1450, survey, f)] = mag return mag
def calcADUwrapper(sedName=None, magNorm=None, redshift=None, internalAv=None, internalRv=None, galacticAv=None, galacticRv=None, bandpass=None): """ Read in an SED and calculat the number of ADU produced by that SED in a specified bandpass Parameters ---------- sedName is a string specifying the file name of the SED magNorm is the normalizing magnitude of the SED in the imsimBandpass redshift is the redshift of the SED internalAv is the Av due to internal dust of the source (if a galaxy) internalRv is the Rv due to internal dust of the source (if a galaxy) galacticAv is the Av due to Milky Way dust between observer and source galacticRv is the Rv due to Milky Way dust between observer and source bandpass is an intantiation of Bandpass representing the band in which the ADUs are measured Returns ------- A float representing the number of ADUs measured in the bandpass """ imsimband = Bandpass() imsimband.imsimBandpass() sed = Sed() sed.readSED_flambda(sedName) fNorm = sed.calcFluxNorm(magNorm, imsimband) sed.multiplyFluxNorm(fNorm) if internalAv is not None and internalRv is not None: if internalAv != 0.0 and internalRv != 0.0: a_int, b_int = sed.setupCCM_ab() sed.addDust(a_int, b_int, A_v=internalAv, R_v=internalRv) if redshift is not None and redshift != 0.0: sed.redshiftSED(redshift, dimming=True) a_int, b_int = sed.setupCCM_ab() sed.addDust(a_int, b_int, A_v=galacticAv, R_v=galacticRv) adu = sed.calcADU(bandpass, photParams=PhotometricParameters()) return adu
def loadBC03(self, subset=None): """ This loads the Bruzual and Charlot SEDs that are currently in the SIMS_SED_LIBRARY. If the user wants to use different SEDs another loading method can be created and used in place of this. @param [in] subset is the list of the subset of files in the galDir that the user can specify if using all the SEDs in the directory is not desired. @param [out] sedList is the set of model SED spectra objects to be passed onto the matching routines. """ if self.galDir is None: raise ValueError( 'self.galDir is None. Add path to galaxy directory.') files = [] if subset is None: for fileName in os.listdir(self.galDir): files.append(fileName) else: for fileName in subset: files.append(fileName) numFiles = len(files) numOn = 0 sedList = [] for fileName in files: if numOn % 100 == 0: print('Loading %i of %i: BC Galaxy SEDs' % (numOn, numFiles)) try: spec = Sed() spec.readSED_flambda(str(self.galDir + '/' + fileName)) spec.name = fileName fileNameAsList = fileName.split('.') spec.type = fileNameAsList[0] spec.age = float(fileNameAsList[1]) metallicity = fileNameAsList[2].split('Z')[0] #Final form is z/zSun spec.metallicity = float(metallicity) * (10**( (len(metallicity) - 1) * -1)) except: continue sedList.append(spec) numOn += 1 return sedList
def setUpClass(cls): lsstDefaults=LSSTdefaults() cls.dbName = 'uncertaintyTestDB.db' if os.path.exists(cls.dbName): os.unlink(cls.dbName) default_obs_metadata = makePhoSimTestDB(filename=cls.dbName, size=10, radius = 5.0) bandpass = ['u', 'g', 'r', 'i', 'z', 'y'] m5 = lsstDefaults._m5.values() cls.obs_metadata = ObservationMetaData( pointingRA = default_obs_metadata.pointingRA, pointingDec = default_obs_metadata.pointingDec, rotSkyPos = default_obs_metadata.rotSkyPos, bandpassName = bandpass, m5 = m5 ) cls.obs_metadata.setBandpassM5andSeeing(bandpassName=bandpass, m5=m5) cls.driver = 'sqlite' cls.host = '' cls.skySeds = [] cls.hardwareBandpasses = [] cls.totalBandpasses = [] cls.bandpasses = ['u', 'g', 'r', 'i', 'z', 'y'] components = ['detector.dat', 'm1.dat', 'm2.dat', 'm3.dat', 'lens1.dat', 'lens2.dat', 'lens3.dat'] for b in cls.bandpasses: bandpassDummy = Bandpass() bandpassDummy.readThroughput(os.path.join(lsst.utils.getPackageDir('throughputs'), 'baseline', 'total_%s.dat' % b)) cls.totalBandpasses.append(bandpassDummy) for b in cls.bandpasses: finalComponents = [] for c in components: finalComponents.append(os.path.join(lsst.utils.getPackageDir('throughputs'), 'baseline', c)) finalComponents.append(os.path.join(lsst.utils.getPackageDir('throughputs'), 'baseline', 'filter_%s.dat' %b)) bandpassDummy = Bandpass() bandpassDummy.readThroughputList(finalComponents) cls.hardwareBandpasses.append(bandpassDummy) for i in range(len(cls.bandpasses)): sedDummy = Sed() sedDummy.readSED_flambda(os.path.join(lsst.utils.getPackageDir('throughputs'), 'baseline', 'darksky.dat')) normalizedSedDummy = setM5(cls.obs_metadata.m5[cls.bandpasses[i]], sedDummy, cls.totalBandpasses[i], cls.hardwareBandpasses[i], FWHMeff=lsstDefaults.FWHMeff(cls.bandpasses[i]), photParams=PhotometricParameters()) cls.skySeds.append(normalizedSedDummy)
def loadmltSEDs(self, subset=None): """ By default will load all seds in mlt directory. The user can also define a subset of what's in the directory and load only those SEDs instead. Will skip over extraneous files in sed folder. @param [in] subset is the list of the subset of files wanted if one doesn't want all files in the mlt directory. @param [out] sedList is the set of model SED spectra objects to be passed onto the matching routines. """ if self.mltDir is None: try: self.mltDir = str(self.sEDDir + '/' + self.specMapDict['mlt'] + '/') except: raise ValueError( str('self.mltDir is None. ' + 'Add path to mlt directory.')) files = [] if subset is None: for fileName in os.listdir(self.mltDir): files.append(fileName) else: for fileName in subset: files.append(fileName) numFiles = len(files) numOn = 0 sedList = [] for fileName in files: if numOn % 100 == 0: print('Loading %i of %i: MLT SEDs' % (numOn, numFiles)) try: spec = Sed() spec.readSED_flambda(str(self.mltDir + '/' + fileName)) spec.name = fileName except: continue sedList.append(spec) numOn += 1 return sedList
def loadBC03(self, subset = None): """ This loads the Bruzual and Charlot SEDs that are currently in the SIMS_SED_LIBRARY. If the user wants to use different SEDs another loading method can be created and used in place of this. @param [in] subset is the list of the subset of files in the galDir that the user can specify if using all the SEDs in the directory is not desired. @param [out] sedList is the set of model SED spectra objects to be passed onto the matching routines. """ if self.galDir is None: raise ValueError('self.galDir is None. Add path to galaxy directory.') files = [] if subset is None: for fileName in os.listdir(self.galDir): files.append(fileName) else: for fileName in subset: files.append(fileName) numFiles = len(files) numOn = 0 sedList = [] for fileName in files: if numOn % 100 == 0: print('Loading %i of %i: BC Galaxy SEDs' % (numOn, numFiles)) try: spec = Sed() spec.readSED_flambda(str(self.galDir + '/' + fileName)) spec.name = fileName fileNameAsList = fileName.split('.') spec.type = fileNameAsList[0] spec.age = float(fileNameAsList[1]) metallicity = fileNameAsList[2].split('Z')[0] #Final form is z/zSun spec.metallicity = float(metallicity) * (10 ** ((len(metallicity)-1)*-1)) except: continue sedList.append(spec) numOn += 1 return sedList
def loadmltSEDs(self, subset = None): """ By default will load all seds in mlt directory. The user can also define a subset of what's in the directory and load only those SEDs instead. Will skip over extraneous files in sed folder. @param [in] subset is the list of the subset of files wanted if one doesn't want all files in the mlt directory. @param [out] sedList is the set of model SED spectra objects to be passed onto the matching routines. """ if self.mltDir is None: try: self.mltDir = str(self.sEDDir + '/' + self.specMapDict['mlt'] + '/') except: raise ValueError(str('self.mltDir is None. ' + 'Add path to mlt directory.')) files = [] if subset is None: for fileName in os.listdir(self.mltDir): files.append(fileName) else: for fileName in subset: files.append(fileName) numFiles = len(files) numOn = 0 sedList = [] for fileName in files: if numOn % 100 == 0: print('Loading %i of %i: MLT SEDs' % (numOn, numFiles)) try: spec = Sed() spec.readSED_flambda(str(self.mltDir + '/' + fileName)) spec.name = fileName except: continue sedList.append(spec) numOn += 1 return sedList
def Get_SED_Restframe(self, Sed_time): a = 1. / (1. + self.z) bandpass_besselb = Bandpass( wavelen=sncosmo.get_bandpass('bessellB').wave, sb=sncosmo.get_bandpass('bessellB').trans) print 'before', Sed_time.wavelen, Sed_time.flambda #print 'there we go',Sed_time.wavelen,Sed_time.flambda SED_rest = Sed(wavelen=Sed_time.wavelen * a * 10., flambda=Sed_time.flambda * np.power(self.lumidist, 2.) / a / 10. / HC_ERG_AA) print 'hello', Sed_time.wavelen * a * 10, Sed_time.flambda * np.power( self.lumidist, 2.) / a / 10. / HC_ERG_AA print 'heelp', SED_rest.wavelen, SED_rest.flambda SED_new = Sed(wavelen=SED_rest.wavelen / a, flambda=a * SED_rest.flambda / np.power(self.lumidist, 2.)) #print 'ici',SED_new.wavelen,SED_new.flambda #estimate the flux in the B band bessellb flux_B_rest = SED_rest.calcFlux(bandpass=bandpass_besselb) flux_B_new = SED_new.calcFlux(bandpass=bandpass_besselb) #now the magnitudes (apparent and absolute) vega_SED = Sed() vega_SED.readSED_flambda('vega.txt') flux_vega = vega_SED.calcFlux(bandpass=bandpass_besselb) mag_B_rest = -2.5 * np.log10(flux_B_rest / flux_vega) mag_B_new = -2.5 * np.log10(flux_B_new / 3631.) print 'hello', len(vega_SED.wavelen), len(vega_SED.flambda), len( bandpass_besselb.sb), flux_vega, flux_B_rest bwave = bandpass_besselb.wavelen btrans = bandpass_besselb.sb vega_wave = vega_SED.wavelen vega_flambda = vega_SED.flambda mask = ((vega_wave > bwave[0]) & (vega_wave < bwave[-1])) d = vega_wave[mask] f = vega_flambda[mask] trans = np.interp(d, bwave, btrans) binw = np.gradient(d) ftot = np.sum(f * trans * binw) print 'vega flux', flux_vega, ftot return SED_rest, mag_B_rest, mag_B_new
def _create_sed_library_mags(wav_min, wav_width): """ Calculate the magnitudes of the SEDs in sims_sed_library dir in the tophat filters specified by wav_min, wav_width Parameters ---------- wav_min is a numpy array of the minimum wavelengths of the tophat filters (in nm) wav_width is a numpy array of the widths of the tophat filters (in nm) Returns ------- sed_names is an array containing the names of the SED files sed_mag_list is MxN float array, with M = number of SED files in the library, and N = number of top hat filters in the catalog sed_mag_norm is 1d float array, with length = number of SED files in the library """ wav_max = max((wav0 + width for wav0, width in zip(wav_min, wav_width))) wav_grid = np.arange(wav_min.min(), wav_max, 0.1) bp_name_list = list() bp_list = list() for wav0, width in zip(wav_min, wav_width): sb_grid = ((wav_grid >= wav0) & (wav_grid <= (wav0 + width))).astype(float) bp_list.append(Bandpass(wavelen=wav_grid, sb=sb_grid)) bp_name_list.append('%d_%d' % (wav0, width)) bandpass_dict = BandpassDict(bp_list, bp_name_list) sed_names = list() sed_mag_list = list() sed_mag_norm = list() imsim_bp = Bandpass() imsim_bp.imsimBandpass() for sed_file_name in os.listdir(_galaxy_sed_dir): spec = Sed() spec.readSED_flambda(os.path.join(_galaxy_sed_dir, sed_file_name)) sed_names.append(defaultSpecMap[sed_file_name]) sed_mag_list.append(tuple(bandpass_dict.magListForSed(spec))) sed_mag_norm.append(spec.calcMag(imsim_bp)) return np.array(sed_names), np.array(sed_mag_list), np.array(sed_mag_norm)
def _calcSingleGalSimSed(self, sedName, zz, iAv, iRv, gAv, gRv, norm): """ correct the SED for redshift, dust, etc. Return an Sed object as defined in sims_photUtils/../../Sed.py """ if _is_null(sedName): return None sed = Sed() sed.readSED_flambda(os.path.join(self.sedDir, sedName)) imsimband = Bandpass() imsimband.imsimBandpass() # normalize the SED # Consulting the file sed.py in GalSim/galsim/ it appears that GalSim expects # its SEDs to ultimately be in units of ergs/nm so that, when called, they can # be converted to photons/nm (see the function __call__() and the assignment of # self._rest_photons in the __init__() of galsim's sed.py file). Thus, we need # to read in our SEDs, normalize them, and then multiply by the exposure time # and the effective area to get from ergs/s/cm^2/nm to ergs/nm. # # The gain parameter should convert between photons and ADU (so: it is the # traditional definition of "gain" -- electrons per ADU -- multiplied by the # quantum efficiency of the detector). Because we fold the quantum efficiency # of the detector into our total_[u,g,r,i,z,y].dat bandpass files # (see the readme in the THROUGHPUTS_DIR/baseline/), we only need to multiply # by the electrons per ADU gain. # # We will take these parameters from an instantiation of the PhotometricParameters # class (which can be reassigned by defining a daughter class of this class) # fNorm = sed.calcFluxNorm(norm, imsimband) sed.multiplyFluxNorm(fNorm) # apply dust extinction (internal) if iAv != 0.0 and iRv != 0.0: a_int, b_int = sed.setupCCM_ab() sed.addDust(a_int, b_int, A_v=iAv, R_v=iRv) # 22 June 2015 # apply redshift; there is no need to apply the distance modulus from # sims/photUtils/CosmologyWrapper; magNorm takes that into account # however, magNorm does not take into account cosmological dimming if zz != 0.0: sed.redshiftSED(zz, dimming=True) # apply dust extinction (galactic) if gAv != 0.0 and gRv != 0.0: a_int, b_int = sed.setupCCM_ab() sed.addDust(a_int, b_int, A_v=gAv, R_v=gRv) return sed
def testSignalToNoise(self): """ Test that calcSNR_m5 and calcSNR_sed give similar results """ defaults = LSSTdefaults() photParams = PhotometricParameters() m5 = [] for i in range(len(self.hardwareList)): m5.append(snr.calcM5(self.skySed, self.bpList[i], self.hardwareList[i], photParams, seeing=defaults.seeing(self.filterNameList[i]))) sedDir = lsst.utils.getPackageDir('sims_sed_library') sedDir = os.path.join(sedDir, 'starSED', 'kurucz') fileNameList = os.listdir(sedDir) numpy.random.seed(42) offset = numpy.random.random_sample(len(fileNameList))*2.0 for ix, name in enumerate(fileNameList): if ix>100: break spectrum = Sed() spectrum.readSED_flambda(os.path.join(sedDir, name)) ff = spectrum.calcFluxNorm(m5[2]-offset[ix], self.bpList[2]) spectrum.multiplyFluxNorm(ff) magList = [] controlList = [] magList = [] for i in range(len(self.bpList)): controlList.append(snr.calcSNR_sed(spectrum, self.bpList[i], self.skySed, self.hardwareList[i], photParams, defaults.seeing(self.filterNameList[i]))) magList.append(spectrum.calcMag(self.bpList[i])) testList, gammaList = snr.calcSNR_m5(numpy.array(magList), numpy.array(self.bpList), numpy.array(m5), photParams) for tt, cc in zip(controlList, testList): msg = '%e != %e ' % (tt, cc) self.assertTrue(numpy.abs(tt/cc - 1.0) < 0.001, msg=msg)
def 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 calcColors(sedname='C.dat'): # Calculate SSO colors. filterdir = os.getenv('LSST_THROUGHPUTS_BASELINE') filterlist = ('u', 'g', 'r', 'i', 'z', 'y') lsst ={} for f in filterlist: lsst[f] = Bandpass() lsst[f].readThroughput(os.path.join(filterdir, 'total_'+f+'.dat')) vband = Bandpass() vband.readThroughput('harris_V.dat') csed = Sed() csed.readSED_flambda(sedname) vmag = csed.calcMag(vband) dmags = {} for f in filterlist: dmags[f] = csed.calcMag(lsst[f]) - vmag return dmags
def testNoSystematicUncertainty(self): """ Test that systematic uncertainty is handled correctly when set to None. """ m5_list = [23.5, 24.3, 22.1, 20.0, 19.5, 21.7] photParams= PhotometricParameters(sigmaSys=0.0) obs_metadata = ObservationMetaData(pointingRA=23.0, pointingDec=45.0, m5=m5_list, bandpassName=self.filterNameList) magnitude_list = [] for bp in self.bpList: mag = self.starSED.calcMag(bp) magnitude_list.append(mag) skySedList = [] for bp, hardware, filterName, mm, m5 in \ zip(self.bpList, self.hardwareList, self.filterNameList, magnitude_list, m5_list): skyDummy = Sed() skyDummy.readSED_flambda(os.path.join(lsst.utils.getPackageDir('throughputs'), 'baseline', 'darksky.dat')) normalizedSkyDummy = setM5(obs_metadata.m5[filterName], skyDummy, bp, hardware, FWHMeff=LSSTdefaults().FWHMeff(filterName), photParams=photParams) sigma, gamma = snr.calcMagError_m5(mm, bp, m5, photParams) snrat = snr.calcSNR_sed(self.starSED, bp, normalizedSkyDummy, hardware, FWHMeff=LSSTdefaults().FWHMeff(filterName), photParams=PhotometricParameters()) testSNR, gamma = snr.calcSNR_m5(mm, bp, m5, photParams=PhotometricParameters(sigmaSys=0.0)) self.assertAlmostEqual(snrat, testSNR, 10, msg = 'failed on calcSNR_m5 test %e != %e ' \ % (snrat, testSNR)) control = snr.magErrorFromSNR(testSNR) msg = '%e is not %e; failed' % (sigma, control) self.assertAlmostEqual(sigma, control, 10, msg=msg)
def testNoSystematicUncertainty(self): """ Test that systematic uncertainty is handled correctly when set to None. """ m5 = [23.5, 24.3, 22.1, 20.0, 19.5, 21.7] photParams= PhotometricParameters(sigmaSys=0.0) obs_metadata = ObservationMetaData(unrefractedRA=23.0, unrefractedDec=45.0, m5=m5, bandpassName=self.filterNameList) magnitudes = [] for bp in self.bpList: mag = self.starSED.calcMag(bp) magnitudes.append(mag) skySedList = [] for bp, hardware, filterName in zip(self.bpList, self.hardwareList, self.filterNameList): skyDummy = Sed() skyDummy.readSED_flambda(os.path.join(lsst.utils.getPackageDir('throughputs'), 'baseline', 'darksky.dat')) normalizedSkyDummy = setM5(obs_metadata.m5[filterName], skyDummy, bp, hardware, seeing=LSSTdefaults().seeing(filterName), photParams=photParams) skySedList.append(normalizedSkyDummy) sigmaList = snr.calcMagError_m5(numpy.array(magnitudes), numpy.array(self.bpList), \ numpy.array(m5), photParams) for i in range(len(self.bpList)): snrat = snr.calcSNR_sed(self.starSED, self.bpList[i], skySedList[i], self.hardwareList[i], seeing=LSSTdefaults().seeing(self.filterNameList[i]), photParams=PhotometricParameters()) testSNR, gamma = snr.calcSNR_m5(numpy.array([magnitudes[i]]), [self.bpList[i]], numpy.array([m5[i]]), photParams=PhotometricParameters(sigmaSys=0.0)) self.assertAlmostEqual(snrat, testSNR[0], 10, msg = 'failed on calcSNR_m5 test %e != %e ' \ % (snrat, testSNR[0])) control = snr.magErrorFromSNR(testSNR) msg = '%e is not %e; failed' % (sigmaList[i], control) self.assertAlmostEqual(sigmaList[i], control, 10, msg=msg)
def test_stars(self): obs = ObservationMetaData(bandpassName=['c_u', 'c_g'], m5=[25.0, 26.0]) db_dtype = np.dtype([('id', np.int), ('raJ2000', np.float), ('decJ2000', np.float), ('sedFilename', str, 100), ('magNorm', np.float), ('galacticAv', np.float)]) inputDir = os.path.join(getPackageDir('sims_catUtils'), 'tests', 'testData') inputFile = os.path.join(inputDir, 'IndicesTestCatalogStars.txt') db = fileDBObject(inputFile, dtype=db_dtype, runtable='test', idColKey='id') cat = CartoonStars(db, obs_metadata=obs) with lsst.utils.tests.getTempFilePath('.txt') as catName: cat.write_catalog(catName) dtype = np.dtype([(name, np.float) for name in cat.column_outputs]) controlData = np.genfromtxt(catName, dtype=dtype, delimiter=',') db_columns = db.query_columns([ 'id', 'raJ2000', 'decJ2000', 'sedFilename', 'magNorm', 'galacticAv' ]) sedDir = os.path.join(getPackageDir('sims_sed_library'), 'starSED', 'kurucz') for ix, line in enumerate(next(db_columns)): spectrum = Sed() spectrum.readSED_flambda(os.path.join(sedDir, line[3])) fnorm = spectrum.calcFluxNorm(line[4], self.normband) spectrum.multiplyFluxNorm(fnorm) a_x, b_x = spectrum.setupCCM_ab() spectrum.addDust(a_x, b_x, A_v=line[5]) umag = spectrum.calcMag(self.uband) self.assertAlmostEqual(umag, controlData['cartoon_u'][ix], 3) gmag = spectrum.calcMag(self.gband) self.assertAlmostEqual(gmag, controlData['cartoon_g'][ix], 3) umagError, gamma = calcMagError_m5(umag, self.uband, obs.m5['c_u'], PhotometricParameters()) gmagError, gamma = calcMagError_m5(gmag, self.gband, obs.m5['c_g'], PhotometricParameters()) self.assertAlmostEqual(umagError, controlData['sigma_cartoon_u'][ix], 3) self.assertAlmostEqual(gmagError, controlData['sigma_cartoon_g'][ix], 3)
def setup_photUtils(): throughputDir = os.getenv("LSST_THROUGHPUTS_DEFAULT") filterlist = ("u", "g", "r", "i", "z", "y") hardware = {} system = {} corecomponents = ["detector.dat", "lens1.dat", "lens2.dat", "lens3.dat", "m1.dat", "m2.dat", "m3.dat"] for f in filterlist: hardware[f] = Bandpass() system[f] = Bandpass() componentlist = copy.deepcopy(corecomponents) componentlist += ["filter_%s.dat" % f] hardware[f].readThroughputList(componentlist, rootDir=throughputDir) componentlist += ["atmos_10.dat"] system[f].readThroughputList(componentlist, rootDir=throughputDir) darksky = Sed() darksky.readSED_flambda(os.path.join(throughputDir, "darksky.dat")) return hardware, system, darksky
def calcWDColors(): """ Calculate a few example WD colors. Values to go in stellarMags(). Here in case values need to be regenerated (different stars, bandpasses change, etc.) """ try: from lsst.utils import getPackageDir import os from lsst.sims.photUtils import Bandpass, Sed except: 'Need to setup sims_photUtils to generate WD magnitudes.' names = ['HeWD_25200_80', 'WD_11000_85', 'WD_3000_85'] fns = [ 'bergeron_He_24000_80.dat_25200.gz', 'bergeron_10500_85.dat_11000.gz', 'bergeron_2750_85.dat_3000.gz' ] wdDir = os.path.join(getPackageDir('sims_sed_library'), 'starSED/wDs/') files = [os.path.join(wdDir, filename) for filename in fns] # Read in the LSST bandpasses bpNames = ['u', 'g', 'r', 'i', 'z', 'y'] bps = [] throughPath = os.path.join(getPackageDir('throughputs'), 'baseline') for key in bpNames: bp = np.loadtxt(os.path.join(throughPath, 'filter_' + key + '.dat'), dtype=list(zip(['wave', 'trans'], [float] * 2))) tempB = Bandpass() tempB.setBandpass(bp['wave'], bp['trans']) bps.append(tempB) # Read in the SEDs and compute mags mags = [] for filename in files: star = Sed() star.readSED_flambda(filename) singleMags = [star.calcMag(band) for band in bps] mags.append([singleMags[i - 1] - singleMags[i] for i in range(1, 6)]) for maglist, fn, name in zip(mags, fns, names): format = (name, fn) + tuple(maglist) print("['%s', '%s', %f, %f, %f, %f, %f]" % format)
def testSignalToNoise(self): """ Test that calcSNR_m5 and calcSNR_sed give similar results """ defaults = LSSTdefaults() photParams = PhotometricParameters() m5 = [] for i in range(len(self.hardwareList)): m5.append( snr.calcM5(self.skySed, self.bpList[i], self.hardwareList[i], photParams, FWHMeff=defaults.FWHMeff(self.filterNameList[i]))) sedDir = os.path.join(lsst.utils.getPackageDir('sims_photUtils'), 'tests/cartoonSedTestData/starSed/') sedDir = os.path.join(sedDir, 'kurucz') fileNameList = os.listdir(sedDir) rng = np.random.RandomState(42) offset = rng.random_sample(len(fileNameList)) * 2.0 for ix, name in enumerate(fileNameList): if ix > 100: break spectrum = Sed() spectrum.readSED_flambda(os.path.join(sedDir, name)) ff = spectrum.calcFluxNorm(m5[2] - offset[ix], self.bpList[2]) spectrum.multiplyFluxNorm(ff) for i in range(len(self.bpList)): control_snr = snr.calcSNR_sed( spectrum, self.bpList[i], self.skySed, self.hardwareList[i], photParams, defaults.FWHMeff(self.filterNameList[i])) mag = spectrum.calcMag(self.bpList[i]) test_snr, gamma = snr.calcSNR_m5(mag, self.bpList[i], m5[i], photParams) self.assertLess((test_snr - control_snr) / control_snr, 0.001)
def read_quasar(): # read quasar spectra and redshift homedir = os.getenv("HOME") quasardir = os.path.join(homedir, "seds/quasar") # read zero redshift quasar base = Sed() base.readSED_flambda(os.path.join(quasardir, "quasar.dat")) # redshift #redshifts = [0, 0.1, 0.2, 0.3, 0.5, 0.8, 1.0, 1.3, 1.6, 1.9, 2.2, 2.5] #redshifts = numpy.array(redshifts) redshifts= numpy.arange(0, 2.8, 0.1) quasars = {} for z in redshifts: wavelen, flambda = base.redshiftSED(z, wavelen=base.wavelen, flambda=base.flambda) quasars[z] = Sed(wavelen=wavelen, flambda=flambda) print "# Generated %d quasars at redshifts between %f and %f" %(len(redshifts), redshifts.min(), redshifts.max()) # resample onto the standard bandpass for Bandpass obj's and calculate fnu to speed later calculations for z in redshifts: quasars[z].synchronizeSED(wavelen_min=WMIN, wavelen_max=WMAX, wavelen_step=WSTEP) return quasars, redshifts
def setup_photUtils(): throughputDir = os.getenv('LSST_THROUGHPUTS_DEFAULT') filterlist = ('u', 'g', 'r', 'i', 'z', 'y') hardware = {} system = {} corecomponents = [ 'detector.dat', 'lens1.dat', 'lens2.dat', 'lens3.dat', 'm1.dat', 'm2.dat', 'm3.dat' ] for f in filterlist: hardware[f] = Bandpass() system[f] = Bandpass() componentlist = copy.deepcopy(corecomponents) componentlist += ['filter_%s.dat' % f] hardware[f].readThroughputList(componentlist, rootDir=throughputDir) componentlist += ['atmos_10.dat'] system[f].readThroughputList(componentlist, rootDir=throughputDir) darksky = Sed() darksky.readSED_flambda(os.path.join(throughputDir, 'darksky.dat')) return hardware, system, darksky
def _create_library_one_sed(_galaxy_sed_dir, sed_file_name_list, av_grid, rv_grid, bandpass_dict, out_dict): n_obj = len(av_grid) * len(rv_grid) imsim_bp = Bandpass() imsim_bp.imsimBandpass() t_start = time.time() for i_sed, sed_file_name in enumerate(sed_file_name_list): if i_sed > 0 and i_sed % 10 == 0: duration = (time.time() - t_start) / 3600.0 pred = len(sed_file_name_list) * duration / i_sed print('%d of %d; dur %.2e pred %.2e' % (i_sed, len(sed_file_name_list), duration, pred)) base_spec = Sed() base_spec.readSED_flambda(os.path.join(_galaxy_sed_dir, sed_file_name)) ax, bx = base_spec.setupCCMab() mag_norm = base_spec.calcMag(imsim_bp) sed_names = np.array([defaultSpecMap[sed_file_name]] * n_obj) rv_out_list = np.zeros(n_obj, dtype=float) av_out_list = np.zeros(n_obj, dtype=float) sed_mag_norm = mag_norm * np.ones(n_obj, dtype=float) sed_mag_list = [] i_obj = 0 for av in av_grid: for rv in rv_grid: spec = Sed(wavelen=base_spec.wavelen, flambda=base_spec.flambda) spec.addCCMDust(ax, bx, A_v=av, R_v=rv) av_out_list[i_obj] = av rv_out_list[i_obj] = rv sed_mag_list.append(tuple(bandpass_dict.magListForSed(spec))) i_obj += 1 out_dict[sed_file_name] = (sed_names, sed_mag_norm, sed_mag_list, av_out_list, rv_out_list)
def calcWDColors(): """ Calculate a few example WD colors. Values to go in stellarMags(). Here in case values need to be regenerated (different stars, bandpasses change, etc.) """ try: from lsst.utils import getPackageDir import os from lsst.sims.photUtils import Bandpass, Sed except: 'Need to setup sims_photUtils to generate WD magnitudes.' names = ['HeWD_25200_80', 'WD_11000_85', 'WD_3000_85'] fns = ['bergeron_He_24000_80.dat_25200.gz', 'bergeron_10500_85.dat_11000.gz', 'bergeron_2750_85.dat_3000.gz'] wdDir = os.path.join(getPackageDir('sims_sed_library'), 'starSED/wDs/') files = [os.path.join(wdDir, filename) for filename in fns] # Read in the LSST bandpasses bpNames = ['u', 'g', 'r', 'i', 'z', 'y'] bps = [] throughPath = os.path.join(getPackageDir('throughputs'), 'baseline') for key in bpNames: bp = np.loadtxt(os.path.join(throughPath, 'filter_' + key + '.dat'), dtype=list(zip(['wave', 'trans'], [float] * 2))) tempB = Bandpass() tempB.setBandpass(bp['wave'], bp['trans']) bps.append(tempB) # Read in the SEDs and compute mags mags = [] for filename in files: star = Sed() star.readSED_flambda(filename) singleMags = [star.calcMag(band) for band in bps] mags.append([singleMags[i - 1] - singleMags[i] for i in range(1, 6)]) for maglist, fn, name in zip(mags, fns, names): format = (name, fn) + tuple(maglist) print("['%s', '%s', %f, %f, %f, %f, %f]" % format)
def test_read_sed_flambda(self): """ Test how readSED_flambda handles the reading of SED filenames when we fail to correctly specify their gzipped state. """ scratch_dir = os.path.join(getPackageDir("sims_photUtils"), "tests", "scratchSpace") rng = np.random.RandomState(88) zipped_name = os.path.join(scratch_dir, "zipped_sed.txt.gz") unzipped_name = os.path.join(scratch_dir, "unzipped_sed.txt") if os.path.exists(zipped_name): os.unlink(zipped_name) if os.path.exists(unzipped_name): os.unlink(unzipped_name) wv = np.arange(100.0, 1000.0, 10.0) flux = rng.random_sample(len(wv)) with gzip.open(zipped_name, "wt") as output_file: for ww, ff in zip(wv, flux): output_file.write("%e %e\n" % (ww, ff)) with open(unzipped_name, "wt") as output_file: for ww, ff in zip(wv, flux): output_file.write("%e %e\n" % (ww, ff)) ss = Sed() ss.readSED_flambda(zipped_name) ss.readSED_flambda(zipped_name[:-3]) ss.readSED_flambda(unzipped_name) ss.readSED_flambda(unzipped_name + '.gz') # make sure an error is raised when you try to read # a file that does not exist with self.assertRaises(IOError) as context: ss.readSED_flambda(os.path.join(scratch_dir, "nonsense.txt")) self.assertIn("sed file", context.exception.args[0]) if os.path.exists(zipped_name): os.unlink(zipped_name) if os.path.exists(unzipped_name): os.unlink(unzipped_name)
def test_eq(self): """ Test that __eq__ in Sed works correctly """ sed_dir = os.path.join(getPackageDir('sims_photUtils'), 'tests', 'cartoonSedTestData', 'starSed', 'kurucz') list_of_seds = os.listdir(sed_dir) sedname1 = os.path.join(sed_dir, list_of_seds[0]) sedname2 = os.path.join(sed_dir, list_of_seds[1]) ss1 = Sed() ss1.readSED_flambda(sedname1) ss2 = Sed() ss2.readSED_flambda(sedname2) ss3 = Sed() ss3.readSED_flambda(sedname1) self.assertFalse(ss1 == ss2) self.assertTrue(ss1 != ss2) self.assertTrue(ss1 == ss3) self.assertFalse(ss1 != ss3) ss3.flambdaTofnu() self.assertFalse(ss1 == ss3) self.assertTrue(ss1 != ss3)
def test_eq(self): """ Test that __eq__ in Sed works correctly """ sed_dir = os.path.join(getPackageDir('sims_sed_library'), 'starSED', 'kurucz') list_of_seds = os.listdir(sed_dir) sedname1 = os.path.join(sed_dir, list_of_seds[0]) sedname2 = os.path.join(sed_dir, list_of_seds[1]) ss1 = Sed() ss1.readSED_flambda(sedname1) ss2 = Sed() ss2.readSED_flambda(sedname2) ss3 = Sed() ss3.readSED_flambda(sedname1) self.assertFalse(ss1 == ss2) self.assertTrue(ss1 != ss2) self.assertTrue(ss1 == ss3) self.assertFalse(ss1 != ss3) ss3.flambdaTofnu() self.assertFalse(ss1 == ss3) self.assertTrue(ss1 != ss3)
def test_read_sed_flambda(self): """ Test how readSED_flambda handles the reading of SED filenames when we fail to correctly specify their gzipped state. """ scratch_dir = tempfile.mkdtemp(prefix='test_read_sed_flambda', dir=ROOT) rng = np.random.RandomState(88) zipped_name = os.path.join(scratch_dir, "zipped_sed.txt.gz") unzipped_name = os.path.join(scratch_dir, "unzipped_sed.txt") if os.path.exists(zipped_name): os.unlink(zipped_name) if os.path.exists(unzipped_name): os.unlink(unzipped_name) wv = np.arange(100.0, 1000.0, 10.0) flux = rng.random_sample(len(wv)) with gzip.open(zipped_name, "wt") as output_file: for ww, ff in zip(wv, flux): output_file.write("%e %e\n" % (ww, ff)) with open(unzipped_name, "wt") as output_file: for ww, ff in zip(wv, flux): output_file.write("%e %e\n" % (ww, ff)) ss = Sed() ss.readSED_flambda(zipped_name) ss.readSED_flambda(zipped_name[:-3]) ss.readSED_flambda(unzipped_name) ss.readSED_flambda(unzipped_name+'.gz') # make sure an error is raised when you try to read # a file that does not exist with self.assertRaises(IOError) as context: ss.readSED_flambda(os.path.join(scratch_dir, "nonsense.txt")) self.assertIn("sed file", context.exception.args[0]) if os.path.exists(scratch_dir): shutil.rmtree(scratch_dir)
def testStellarPhotometricUncertainties(self): """ Test in the case of a catalog of stars """ lsstDefaults = LSSTdefaults() starDB = testStarsDBObj(driver=self.driver, host=self.host, database=self.dbName) starCat = testStarCatalog(starDB, obs_metadata=self.obs_metadata) ct = 0 for line in starCat.iter_catalog(): starSed = Sed() starSed.readSED_flambda( os.path.join(getPackageDir('sims_sed_library'), defaultSpecMap[line[14]])) imsimband = Bandpass() imsimband.imsimBandpass() fNorm = starSed.calcFluxNorm(line[15], imsimband) starSed.multiplyFluxNorm(fNorm) aV = np.float(line[16]) a_int, b_int = starSed.setupCCMab() starSed.addCCMDust(a_int, b_int, A_v=aV) for i in range(len(self.bandpasses)): controlSigma = calcMagError_sed( starSed, self.totalBandpasses[i], self.skySeds[i], self.hardwareBandpasses[i], FWHMeff=lsstDefaults.FWHMeff(self.bandpasses[i]), photParams=PhotometricParameters()) testSigma = line[8 + i] self.assertAlmostEqual(controlSigma, testSigma, 4) ct += 1 self.assertGreater(ct, 0)
def testSignalToNoise(self): """ Test that calcSNR_m5 and calcSNR_sed give similar results """ defaults = LSSTdefaults() photParams = PhotometricParameters() m5 = [] for i in range(len(self.hardwareList)): m5.append(snr.calcM5(self.skySed, self.bpList[i], self.hardwareList[i], photParams, FWHMeff=defaults.FWHMeff(self.filterNameList[i]))) sedDir = os.path.join(lsst.utils.getPackageDir('sims_photUtils'), 'tests/cartoonSedTestData/starSed/') sedDir = os.path.join(sedDir, 'kurucz') fileNameList = os.listdir(sedDir) rng = np.random.RandomState(42) offset = rng.random_sample(len(fileNameList))*2.0 for ix, name in enumerate(fileNameList): if ix > 100: break spectrum = Sed() spectrum.readSED_flambda(os.path.join(sedDir, name)) ff = spectrum.calcFluxNorm(m5[2]-offset[ix], self.bpList[2]) spectrum.multiplyFluxNorm(ff) for i in range(len(self.bpList)): control_snr = snr.calcSNR_sed(spectrum, self.bpList[i], self.skySed, self.hardwareList[i], photParams, defaults.FWHMeff(self.filterNameList[i])) mag = spectrum.calcMag(self.bpList[i]) test_snr, gamma = snr.calcSNR_m5(mag, self.bpList[i], m5[i], photParams) self.assertLess((test_snr-control_snr)/control_snr, 0.001)
def test_stars(self): obs = ObservationMetaData(bandpassName=['c_u', 'c_g'], m5=[25.0, 26.0]) db_dtype = np.dtype([('id', np.int), ('raJ2000', np.float), ('decJ2000', np.float), ('sedFilename', str, 100), ('magNorm', np.float), ('galacticAv', np.float)]) inputDir = os.path.join(getPackageDir('sims_catUtils'), 'tests', 'testData') inputFile = os.path.join(inputDir, 'IndicesTestCatalogStars.txt') db = fileDBObject(inputFile, dtype=db_dtype, runtable='test', idColKey='id') cat = CartoonStars(db, obs_metadata=obs) with lsst.utils.tests.getTempFilePath('.txt') as catName: cat.write_catalog(catName) dtype = np.dtype([(name, np.float) for name in cat.column_outputs]) controlData = np.genfromtxt(catName, dtype=dtype, delimiter=',') db_columns = db.query_columns(['id', 'raJ2000', 'decJ2000', 'sedFilename', 'magNorm', 'galacticAv']) sedDir = os.path.join(getPackageDir('sims_sed_library'), 'starSED', 'kurucz') for ix, line in enumerate(next(db_columns)): spectrum = Sed() spectrum.readSED_flambda(os.path.join(sedDir, line[3])) fnorm = spectrum.calcFluxNorm(line[4], self.normband) spectrum.multiplyFluxNorm(fnorm) a_x, b_x = spectrum.setupCCM_ab() spectrum.addDust(a_x, b_x, A_v=line[5]) umag = spectrum.calcMag(self.uband) self.assertAlmostEqual(umag, controlData['cartoon_u'][ix], 3) gmag = spectrum.calcMag(self.gband) self.assertAlmostEqual(gmag, controlData['cartoon_g'][ix], 3) umagError, gamma = calcMagError_m5(umag, self.uband, obs.m5['c_u'], PhotometricParameters()) gmagError, gamma = calcMagError_m5(gmag, self.gband, obs.m5['c_g'], PhotometricParameters()) self.assertAlmostEqual(umagError, controlData['sigma_cartoon_u'][ix], 3) self.assertAlmostEqual(gmagError, controlData['sigma_cartoon_g'][ix], 3)
def create_k_corr_grid(redshift): """ (Edited from original because of error) Returns a grid of redshifts and K corrections on the LSST Simulations AGN SED that can be used for K correction interpolation. """ bp_dict = BandpassDict.loadTotalBandpassesFromFiles() bp_i = bp_dict['i'] sed_dir = os.path.join(getPackageDir('sims_sed_library'), 'agnSED') sed_name = os.path.join(sed_dir, 'agn.spec.gz') if not os.path.exists(sed_name): raise RuntimeError('\n\n%s\n\nndoes not exist\n\n' % sed_name) base_sed = Sed() base_sed.readSED_flambda(sed_name) z_grid = np.arange(0.0, redshift.max(), 0.01) k_grid = np.zeros(len(z_grid), dtype=float) for i_z, zz in enumerate(z_grid): ss = Sed(flambda=base_sed.flambda, wavelen=base_sed.wavelen) ss.redshiftSED(zz, dimming=True) k = k_correction(ss, bp_i, zz) k_grid[i_z] = k return z_grid, k_grid
def test_k_correction(self): """ Test that the K correction correctly converts absolute magnitude to observed magnitude. """ bp_dict = BandpassDict.loadTotalBandpassesFromFiles() rng = np.random.RandomState(41321) sed_dir = os.path.join(getPackageDir('sims_sed_library'), 'galaxySED') list_of_sed_files = os.listdir(sed_dir) list_of_sed_files.sort() sed_to_check = rng.choice(list_of_sed_files, size=10) redshift_arr = rng.random_sample(len(sed_to_check)) * 2.0 + 0.1 bp = bp_dict['g'] for sed_name, zz in zip(sed_to_check, redshift_arr): full_name = os.path.join(sed_dir, sed_name) ss = Sed() ss.readSED_flambda(full_name) true_rest_mag = ss.calcMag(bp) ss.redshiftSED(zz, dimming=True) obs_mag = ss.calcMag(bp) k_corr = k_correction(ss, bp, zz) self.assertLess(np.abs(true_rest_mag - obs_mag + k_corr), 0.001)
def calcADUwrapper(sedName=None, magNorm=None, redshift=None, internalAv=None, internalRv=None, galacticAv=None, galacticRv=None, bandpass=None): imsimband = Bandpass() imsimband.imsimBandpass() sed = Sed() sed.readSED_flambda(sedName) fNorm = sed.calcFluxNorm(magNorm, imsimband) sed.multiplyFluxNorm(fNorm) if internalAv is not None and internalRv is not None: if internalAv != 0.0 and internalRv != 0.0: a_int, b_int = sed.setupCCMab() sed.addCCMDust(a_int, b_int, A_v=internalAv, R_v=internalRv) if redshift is not None and redshift != 0.0: sed.redshiftSED(redshift, dimming=True) a_int, b_int = sed.setupCCMab() sed.addCCMDust(a_int, b_int, A_v=galacticAv, R_v=galacticRv) adu = sed.calcADU(bandpass, photParams=PhotometricParameters()) return adu
def test_cache(self): """ Verify that loading an SED from the cache gives identical results to loading the same SED from ASCII (since we are not calling cache_LSST_seds(), as soon as we load an SED with readSED_flambda, it should get stored in the _global_misc_sed_cache) """ sed_dir = os.path.join(getPackageDir('sims_photUtils'), 'tests', 'cartoonSedTestData', 'starSed', 'kurucz') sed_name_list = os.listdir(sed_dir) msg = ('An SED loaded from the cache is not ' 'identical to the same SED loaded from disk') for ix in range(5): full_name = os.path.join(sed_dir, sed_name_list[ix]) ss_uncache = Sed() ss_uncache.readSED_flambda(full_name) ss_cache = Sed() ss_cache.readSED_flambda(full_name) self.assertEqual(ss_cache, ss_uncache, msg=msg) # test that modifications to an SED don't get pushed # to the cache full_name = os.path.join(sed_dir, sed_name_list[0]) ss1 = Sed() ss1.readSED_flambda(full_name) ss2 = Sed() ss2.readSED_flambda(full_name) ss2.flambda *= 2.0 ss3 = Sed() ss3.readSED_flambda(full_name) msg = "Changes to SED made it into the cache" self.assertEqual(ss1, ss3, msg=msg) self.assertNotEqual(ss1, ss2, msg=msg) self.assertNotEqual(ss2, ss3, msg=msg)
def calcM5(hardware, system, atmos, title='m5'): """ Calculate m5 values for all filters in hardware and system. Prints all values that go into "table 2" of the overview paper. Returns dictionary of m5 values. """ # photParams stores default values for the exposure time, nexp, size of the primary, # readnoise, gain, platescale, etc. # See https://github.com/lsst/sims_photUtils/blob/master/python/lsst/sims/photUtils/PhotometricParameters.py photParams = PhotometricParameters(gain=1) photParams_infinity = PhotometricParameters(readnoise=0, darkcurrent=0, othernoise=0, gain=1) # lsstDefaults stores default values for the FWHMeff. # See https://github.com/lsst/sims_photUtils/blob/master/python/lsst/sims/photUtils/LSSTdefaults.py lsstDefaults = LSSTdefaults() darksky = Sed() darksky.readSED_flambda(os.path.join('../siteProperties', 'darksky.dat')) flatSed = Sed() flatSed.setFlatSED() m5 = {} Tb = {} Sb = {} kAtm = {} Cm = {} dCm_infinity = {} sourceCounts = {} skyCounts = {} skyMag = {} gamma = {} for f in system: m5[f] = SignalToNoise.calcM5(darksky, system[f], hardware[f], photParams, FWHMeff=lsstDefaults.FWHMeff(f)) fNorm = flatSed.calcFluxNorm(m5[f], system[f]) flatSed.multiplyFluxNorm(fNorm) sourceCounts[f] = flatSed.calcADU(system[f], photParams=photParams) # Calculate the Skycounts expected in this bandpass. skyCounts[f] = (darksky.calcADU(hardware[f], photParams=photParams) * photParams.platescale**2) # Calculate the sky surface brightness. skyMag[f] = darksky.calcMag(hardware[f]) # Calculate the gamma value. gamma[f] = SignalToNoise.calcGamma(system[f], m5[f], photParams) # Calculate the "Throughput Integral" (this is the hardware + atmosphere) dwavelen = np.mean(np.diff(system[f].wavelen)) Tb[f] = np.sum(system[f].sb / system[f].wavelen) * dwavelen # Calculate the "Sigma" 'system integral' (this is the hardware only) Sb[f] = np.sum(hardware[f].sb / hardware[f].wavelen) * dwavelen # Calculate km - atmospheric extinction in a particular bandpass kAtm[f] = -2.5*np.log10(Tb[f] / Sb[f]) # Calculate the Cm and Cm_Infinity values. # m5 = Cm + 0.5*(msky - 21) + 2.5log10(0.7/FWHMeff) + 1.25log10(t/30) - km(X-1.0) # Exptime should be 30 seconds and X=1.0 exptime = photParams.exptime * photParams.nexp if exptime != 30.0: print "Whoa, exposure time was not as expected - got %s not 30 seconds. Please edit Cm calculation." %(exptime) # Assumes atmosphere used in system throughput is X=1.0 X = 1.0 Cm[f] = (m5[f] - 0.5*(skyMag[f] - 21) - 2.5*np.log10(0.7/lsstDefaults.FWHMeff(f))) # Calculate Cm_Infinity by setting readout noise to zero. m5inf = SignalToNoise.calcM5(darksky, system[f], hardware[f], photParams_infinity, FWHMeff=lsstDefaults.FWHMeff(f)) Cm_infinity = (m5inf - 0.5*(skyMag[f] - 21) - 2.5*np.log10(0.7/lsstDefaults.FWHMeff(f))) dCm_infinity[f] = Cm_infinity - Cm[f] print title print 'Filter FWHMeff FWHMgeom SkyMag SkyCounts Tb Sb kAtm Gamma Cm dCm_infinity m5 SourceCounts' for f in ('u', 'g' ,'r', 'i', 'z', 'y'): print '%s %.2f %.2f %.2f %.1f %.3f %.3f %.4f %.6f %.2f %.2f %.2f %.2f'\ %(f, lsstDefaults.FWHMeff(f), SignalToNoise.FWHMeff2FWHMgeom(lsstDefaults.FWHMeff(f)), skyMag[f], skyCounts[f], Tb[f], Sb[f], kAtm[f], gamma[f], Cm[f], dCm_infinity[f], m5[f], sourceCounts[f]) # Show what these look like individually (add sky & m5 limits on throughput curves) plt.figure() for f in filterlist: plt.plot(system[f].wavelen, system[f].sb, color=filtercolors[f], linewidth=2, label=f) plt.plot(atmosphere.wavelen, atmosphere.sb, 'k:', label='X=1.0') plt.legend(loc='center right', fontsize='smaller') plt.xlim(300, 1100) plt.ylim(0, 1) plt.xlabel('Wavelength (nm)') plt.ylabel('Throughput') plt.title('System Throughputs') plt.grid(True) plt.figure() ax = plt.gca() # Add dark sky ax2 = ax.twinx() plt.sca(ax2) skyab = -2.5*np.log10(darksky.fnu) - darksky.zp ax2.plot(darksky.wavelen, skyab, 'k-', linewidth=0.8, label='Dark sky mags') ax2.set_ylabel('AB mags') ax2.set_ylim(24, 14) plt.sca(ax) # end of dark sky handles = [] for f in filterlist: plt.plot(system[f].wavelen, system[f].sb, color=filtercolors[f], linewidth=2) myline = mlines.Line2D([], [], color=filtercolors[f], linestyle='-', linewidth=2, label = '%s: m5 %.1f (sky %.1f)' %(f, m5[f], skyMag[f])) handles.append(myline) plt.plot(atmos.wavelen, atmos.sb, 'k:', label='Atmosphere, X=1.0') # Add legend for dark sky. myline = mlines.Line2D([], [], color='k', linestyle='-', label='Dark sky AB mags/arcsec^2') handles.append(myline) # end of dark sky legend line plt.legend(loc=(0.01, 0.69), handles=handles, fancybox=True, numpoints=1, fontsize='small') plt.ylim(0, 1) plt.xlim(300, 1100) plt.xlabel('Wavelength (nm)') plt.ylabel('Fractional Throughput Response') plt.title('System total response curves %s' %(title)) return m5
def _calculateGalSimSeds(self): """ Apply any physical corrections to the objects' SEDS (redshift them, apply dust, etc.). Return a list of Sed objects containing the SEDS """ sedList = [] actualSEDnames = self.column_by_name('sedFilepath') redshift = self.column_by_name('redshift') internalAv = self.column_by_name('internalAv') internalRv = self.column_by_name('internalRv') galacticAv = self.column_by_name('galacticAv') galacticRv = self.column_by_name('galacticRv') magNorm = self.column_by_name('magNorm') #for setting magNorm imsimband = Bandpass() imsimband.imsimBandpass() outputNames=[] for (sedName, zz, iAv, iRv, gAv, gRv, norm) in \ zip(actualSEDnames, redshift, internalAv, internalRv, galacticAv, galacticRv, magNorm): if is_null(sedName): sedList.append(None) else: if sedName in self.uniqueSeds: #we have already read in this file; no need to do it again sed = Sed(wavelen=self.uniqueSeds[sedName].wavelen, flambda=self.uniqueSeds[sedName].flambda, fnu=self.uniqueSeds[sedName].fnu, name=self.uniqueSeds[sedName].name) else: #load the SED of the object sed = Sed() sedFile = os.path.join(self.sedDir, sedName) sed.readSED_flambda(sedFile) flambdaCopy = copy.deepcopy(sed.flambda) #If the SED is zero inside of the bandpass, GalSim raises an error. #This sets a minimum flux value of 1.0e-30 so that the SED is never technically #zero inside of the bandpass. sed.flambda = numpy.array([ff if ff>1.0e-30 else 1.0e-30 for ff in flambdaCopy]) sed.fnu = None #copy the unnormalized file to uniqueSeds so we don't have to read it in again sedCopy = Sed(wavelen=sed.wavelen, flambda=sed.flambda, fnu=sed.fnu, name=sed.name) self.uniqueSeds[sedName] = sedCopy #normalize the SED #Consulting the file sed.py in GalSim/galsim/ it appears that GalSim expects #its SEDs to ultimately be in units of ergs/nm so that, when called, they can #be converted to photons/nm (see the function __call__() and the assignment of #self._rest_photons in the __init__() of galsim's sed.py file). Thus, we need #to read in our SEDs, normalize them, and then multiply by the exposure time #and the effective area to get from ergs/s/cm^2/nm to ergs/nm. # #The gain parameter should convert between photons and ADU (so: it is the #traditional definition of "gain" -- electrons per ADU -- multiplied by the #quantum efficiency of the detector). Because we fold the quantum efficiency #of the detector into our total_[u,g,r,i,z,y].dat bandpass files #(see the readme in the THROUGHPUTS_DIR/baseline/), we only need to multiply #by the electrons per ADU gain. # #We will take these parameters from an instantiation of the PhotometricParameters #class (which can be reassigned by defining a daughter class of this class) # fNorm = sed.calcFluxNorm(norm, imsimband) sed.multiplyFluxNorm(fNorm) #apply dust extinction (internal) if iAv != 0.0 and iRv != 0.0: a_int, b_int = sed.setupCCMab() sed.addCCMDust(a_int, b_int, A_v=iAv, R_v=iRv) #22 June 2015 #apply redshift; there is no need to apply the distance modulus from #sims/photUtils/CosmologyWrapper; magNorm takes that into account #however, magNorm does not take into account cosmological dimming if zz != 0.0: sed.redshiftSED(zz, dimming=True) #apply dust extinction (galactic) a_int, b_int = sed.setupCCMab() sed.addCCMDust(a_int, b_int, A_v=gAv, R_v=gRv) sedList.append(sed) return sedList
class TestSNRmethods(unittest.TestCase): def setUp(self): starName = os.path.join(lsst.utils.getPackageDir('sims_photUtils'), 'tests/cartoonSedTestData/starSed/') starName = os.path.join(starName, 'kurucz', 'km20_5750.fits_g40_5790.gz') self.starSED = Sed() self.starSED.readSED_flambda(starName) imsimband = Bandpass() imsimband.imsimBandpass() fNorm = self.starSED.calcFluxNorm(22.0, imsimband) self.starSED.multiplyFluxNorm(fNorm) hardwareDir = os.path.join(lsst.utils.getPackageDir('throughputs'), 'baseline') componentList = ['detector.dat', 'm1.dat', 'm2.dat', 'm3.dat', 'lens1.dat', 'lens2.dat', 'lens3.dat'] self.skySed = Sed() self.skySed.readSED_flambda(os.path.join(hardwareDir, 'darksky.dat')) totalNameList = ['total_u.dat', 'total_g.dat', 'total_r.dat', 'total_i.dat', 'total_z.dat', 'total_y.dat'] self.bpList = [] self.hardwareList = [] for name in totalNameList: dummy = Bandpass() dummy.readThroughput(os.path.join(hardwareDir, name)) self.bpList.append(dummy) dummy = Bandpass() hardwareNameList = [os.path.join(hardwareDir, name)] for component in componentList: hardwareNameList.append(os.path.join(hardwareDir, component)) dummy.readThroughputList(hardwareNameList) self.hardwareList.append(dummy) self.filterNameList = ['u', 'g', 'r', 'i', 'z', 'y'] def testMagError(self): """ Make sure that calcMagError_sed and calcMagError_m5 agree to within 0.001 """ defaults = LSSTdefaults() photParams = PhotometricParameters() # create a cartoon spectrum to test on spectrum = Sed() spectrum.setFlatSED() spectrum.multiplyFluxNorm(1.0e-9) # find the magnitudes of that spectrum in our bandpasses magList = [] for total in self.bpList: magList.append(spectrum.calcMag(total)) magList = np.array(magList) # try for different normalizations of the skySED for fNorm in np.arange(1.0, 5.0, 1.0): self.skySed.multiplyFluxNorm(fNorm) for total, hardware, filterName, mm in \ zip(self.bpList, self.hardwareList, self.filterNameList, magList): FWHMeff = defaults.FWHMeff(filterName) m5 = snr.calcM5(self.skySed, total, hardware, photParams, FWHMeff=FWHMeff) sigma_sed = snr.calcMagError_sed(spectrum, total, self.skySed, hardware, photParams, FWHMeff=FWHMeff) sigma_m5, gamma = snr.calcMagError_m5(mm, total, m5, photParams) self.assertAlmostEqual(sigma_m5, sigma_sed, 3) def testVerboseSNR(self): """ Make sure that calcSNR_sed has everything it needs to run in verbose mode """ photParams = PhotometricParameters() # create a cartoon spectrum to test on spectrum = Sed() spectrum.setFlatSED() spectrum.multiplyFluxNorm(1.0e-9) snr.calcSNR_sed(spectrum, self.bpList[0], self.skySed, self.hardwareList[0], photParams, FWHMeff=0.7, verbose=True) def testSignalToNoise(self): """ Test that calcSNR_m5 and calcSNR_sed give similar results """ defaults = LSSTdefaults() photParams = PhotometricParameters() m5 = [] for i in range(len(self.hardwareList)): m5.append(snr.calcM5(self.skySed, self.bpList[i], self.hardwareList[i], photParams, FWHMeff=defaults.FWHMeff(self.filterNameList[i]))) sedDir = os.path.join(lsst.utils.getPackageDir('sims_photUtils'), 'tests/cartoonSedTestData/starSed/') sedDir = os.path.join(sedDir, 'kurucz') fileNameList = os.listdir(sedDir) rng = np.random.RandomState(42) offset = rng.random_sample(len(fileNameList))*2.0 for ix, name in enumerate(fileNameList): if ix > 100: break spectrum = Sed() spectrum.readSED_flambda(os.path.join(sedDir, name)) ff = spectrum.calcFluxNorm(m5[2]-offset[ix], self.bpList[2]) spectrum.multiplyFluxNorm(ff) for i in range(len(self.bpList)): control_snr = snr.calcSNR_sed(spectrum, self.bpList[i], self.skySed, self.hardwareList[i], photParams, defaults.FWHMeff(self.filterNameList[i])) mag = spectrum.calcMag(self.bpList[i]) test_snr, gamma = snr.calcSNR_m5(mag, self.bpList[i], m5[i], photParams) self.assertLess((test_snr-control_snr)/control_snr, 0.001) def testSystematicUncertainty(self): """ Test that systematic uncertainty is added correctly. """ sigmaSys = 0.002 m5_list = [23.5, 24.3, 22.1, 20.0, 19.5, 21.7] photParams = PhotometricParameters(sigmaSys=sigmaSys) obs_metadata = ObservationMetaData(pointingRA=23.0, pointingDec=45.0, m5=m5_list, bandpassName=self.filterNameList) magnitude_list = [] for bp in self.bpList: mag = self.starSED.calcMag(bp) magnitude_list.append(mag) for bp, hardware, filterName, mm, m5 in \ zip(self.bpList, self.hardwareList, self.filterNameList, magnitude_list, m5_list): skyDummy = Sed() skyDummy.readSED_flambda(os.path.join(lsst.utils.getPackageDir('throughputs'), 'baseline', 'darksky.dat')) normalizedSkyDummy = setM5(obs_metadata.m5[filterName], skyDummy, bp, hardware, FWHMeff=LSSTdefaults().FWHMeff(filterName), photParams=photParams) sigma, gamma = snr.calcMagError_m5(mm, bp, m5, photParams) snrat = snr.calcSNR_sed(self.starSED, bp, normalizedSkyDummy, hardware, FWHMeff=LSSTdefaults().FWHMeff(filterName), photParams=PhotometricParameters()) testSNR, gamma = snr.calcSNR_m5(mm, bp, m5, photParams=PhotometricParameters(sigmaSys=0.0)) self.assertAlmostEqual(snrat, testSNR, 10, msg = 'failed on calcSNR_m5 test %e != %e ' % (snrat, testSNR)) control = np.sqrt(np.power(snr.magErrorFromSNR(testSNR), 2) + np.power(sigmaSys, 2)) msg = '%e is not %e; failed' % (sigma, control) self.assertAlmostEqual(sigma, control, 10, msg=msg) def testNoSystematicUncertainty(self): """ Test that systematic uncertainty is handled correctly when set to None. """ m5_list = [23.5, 24.3, 22.1, 20.0, 19.5, 21.7] photParams = PhotometricParameters(sigmaSys=0.0) obs_metadata = ObservationMetaData(pointingRA=23.0, pointingDec=45.0, m5=m5_list, bandpassName=self.filterNameList) magnitude_list = [] for bp in self.bpList: mag = self.starSED.calcMag(bp) magnitude_list.append(mag) for bp, hardware, filterName, mm, m5 in \ zip(self.bpList, self.hardwareList, self.filterNameList, magnitude_list, m5_list): skyDummy = Sed() skyDummy.readSED_flambda(os.path.join(lsst.utils.getPackageDir('throughputs'), 'baseline', 'darksky.dat')) normalizedSkyDummy = setM5(obs_metadata.m5[filterName], skyDummy, bp, hardware, FWHMeff=LSSTdefaults().FWHMeff(filterName), photParams=photParams) sigma, gamma = snr.calcMagError_m5(mm, bp, m5, photParams) snrat = snr.calcSNR_sed(self.starSED, bp, normalizedSkyDummy, hardware, FWHMeff=LSSTdefaults().FWHMeff(filterName), photParams=PhotometricParameters()) testSNR, gamma = snr.calcSNR_m5(mm, bp, m5, photParams=PhotometricParameters(sigmaSys=0.0)) self.assertAlmostEqual(snrat, testSNR, 10, msg = 'failed on calcSNR_m5 test %e != %e ' % (snrat, testSNR)) control = snr.magErrorFromSNR(testSNR) msg = '%e is not %e; failed' % (sigma, control) self.assertAlmostEqual(sigma, control, 10, msg=msg) def testFWHMconversions(self): FWHMeff = 0.8 FWHMgeom = snr.FWHMeff2FWHMgeom(FWHMeff) self.assertEqual(FWHMgeom, (0.822*FWHMeff+0.052)) FWHMgeom = 0.8 FWHMeff = snr.FWHMgeom2FWHMeff(FWHMgeom) self.assertEqual(FWHMeff, (FWHMgeom-0.052)/0.822) def testSNR_arr(self): """ Test that calcSNR_m5 works on numpy arrays of magnitudes """ rng = np.random.RandomState(17) mag_list = rng.random_sample(100)*5.0 + 15.0 photParams = PhotometricParameters() bp = self.bpList[0] m5 = 24.0 control_list = [] for mm in mag_list: ratio, gamma = snr.calcSNR_m5(mm, bp, m5, photParams) control_list.append(ratio) control_list = np.array(control_list) test_list, gamma = snr.calcSNR_m5(mag_list, bp, m5, photParams) np.testing.assert_array_equal(control_list, test_list) def testError_arr(self): """ Test that calcMagError_m5 works on numpy arrays of magnitudes """ rng = np.random.RandomState(17) mag_list = rng.random_sample(100)*5.0 + 15.0 photParams = PhotometricParameters() bp = self.bpList[0] m5 = 24.0 control_list = [] for mm in mag_list: sig, gamma = snr.calcMagError_m5(mm, bp, m5, photParams) control_list.append(sig) control_list = np.array(control_list) test_list, gamma = snr.calcMagError_m5(mag_list, bp, m5, photParams) np.testing.assert_array_equal(control_list, test_list)
def testObjectPlacement(self): """ Test that GalSim places objects on the correct pixel by drawing images, reading them in, and then comparing the flux contained in circles of 2 fwhm radii about the object's expected positions with the actual expected flux of the objects. """ scratchDir = os.path.join(getPackageDir('sims_GalSimInterface'), 'tests', 'scratchSpace') catName = os.path.join(scratchDir, 'placementCatalog.dat') imageRoot = os.path.join(scratchDir, 'placementImage') dbFileName = os.path.join(scratchDir, 'placementInputCatalog.dat') cameraDir = os.path.join(getPackageDir('sims_GalSimInterface'), 'tests', 'cameraData') camera = ReturnCamera(cameraDir) detector = camera[0] imageName = '%s_%s_u.fits' % (imageRoot, detector.getName()) controlSed = Sed() controlSed.readSED_flambda( os.path.join(getPackageDir('sims_sed_library'), 'flatSED','sed_flat.txt.gz') ) uBandpass = Bandpass() uBandpass.readThroughput( os.path.join(getPackageDir('throughputs'), 'baseline','total_u.dat') ) controlBandpass = Bandpass() controlBandpass.imsimBandpass() ff = controlSed.calcFluxNorm(self.magNorm, uBandpass) controlSed.multiplyFluxNorm(ff) a_int, b_int = controlSed.setupCCMab() controlSed.addCCMDust(a_int, b_int, A_v=0.1, R_v=3.1) nSamples = 5 numpy.random.seed(42) pointingRaList = numpy.random.random_sample(nSamples)*360.0 pointingDecList = numpy.random.random_sample(nSamples)*180.0 - 90.0 rotSkyPosList = numpy.random.random_sample(nSamples)*360.0 fwhmList = numpy.random.random_sample(nSamples)*1.0 + 0.3 actualCounts = None for pointingRA, pointingDec, rotSkyPos, fwhm in \ zip(pointingRaList, pointingDecList, rotSkyPosList, fwhmList): obs = ObservationMetaData(unrefractedRA=pointingRA, unrefractedDec=pointingDec, boundType='circle', boundLength=4.0, mjd=49250.0, rotSkyPos=rotSkyPos) xDisplacementList = numpy.random.random_sample(nSamples)*60.0-30.0 yDisplacementList = numpy.random.random_sample(nSamples)*60.0-30.0 create_text_catalog(obs, dbFileName, xDisplacementList, yDisplacementList, mag_norm=[self.magNorm]*len(xDisplacementList)) db = placementFileDBObj(dbFileName, runtable='test') cat = placementCatalog(db, obs_metadata=obs) if actualCounts is None: actualCounts = controlSed.calcADU(uBandpass, cat.photParams) psf = SNRdocumentPSF(fwhm=fwhm) cat.setPSF(psf) cat.camera = camera cat.write_catalog(catName) cat.write_images(nameRoot=imageRoot) objRaList = [] objDecList = [] with open(catName, 'r') as inFile: for line in inFile: if line[0] != '#': words = line.split(';') objRaList.append(numpy.radians(numpy.float(words[2]))) objDecList.append(numpy.radians(numpy.float(words[3]))) objRaList = numpy.array(objRaList) objDecList = numpy.array(objDecList) self.check_placement(imageName, objRaList, objDecList, [fwhm]*len(objRaList), numpy.array([actualCounts]*len(objRaList)), cat.photParams.gain, detector, camera, obs, epoch=2000.0) if os.path.exists(dbFileName): os.unlink(dbFileName) if os.path.exists(catName): os.unlink(catName) if os.path.exists(imageName): os.unlink(imageName)
def _quiescentMagnitudeGetter(self, bandpassDict, columnNameList, bandpassTag='lsst'): """ Method that actually does the work calculating magnitudes for solar system objects. Because solar system objects have no dust extinction, this method works by loading each unique Sed once, normalizing it, calculating its magnitudes in the desired bandpasses, and then storing the normalizing magnitudes and the bandpass magnitudes in a dict. Magnitudes for subsequent objects with identical Seds will be calculated by adding an offset to the magnitudes. The offset is determined by comparing normalizing magnitues. @param [in] bandpassDict is an instantiation of BandpassDict representing the bandpasses to be integrated over @param [in] columnNameList is a list of the names of the columns being calculated by this getter @param [in] bandpassTag (optional) is a string indicating the name of the bandpass system (i.e. 'lsst', 'sdss', etc.). This is in case the user wants to calculate the magnitudes in multiple systems simultaneously. In that case, the dict will store magnitudes for each Sed in each magnitude system separately. @param [out] a numpy array of magnitudes corresponding to bandpassDict. """ # figure out which of these columns we are actually calculating indices = [ii for ii, name in enumerate(columnNameList) if name in self._actually_calculated_columns] if len(indices) == len(columnNameList): indices = None if not hasattr(self, '_ssmMagDict'): self._ssmMagDict = {} self._ssmMagNormDict = {} self._file_dir = getPackageDir('sims_sed_library') self._spec_map = defaultSpecMap self._normalizing_bandpass = Bandpass() self._normalizing_bandpass.imsimBandpass() sedNameList = self.column_by_name('sedFilename') magNormList = self.column_by_name('magNorm') if len(sedNameList)==0: # need to return something when InstanceCatalog goes through # it's "dry run" to determine what columns are required from # the database return np.zeros((len(bandpassDict.keys()),0)) magListOut = [] for sedName, magNorm in zip(sedNameList, magNormList): magTag = bandpassTag+'_'+sedName if sedName not in self._ssmMagNormDict or magTag not in self._ssmMagDict: dummySed = Sed() dummySed.readSED_flambda(os.path.join(self._file_dir, self._spec_map[sedName])) fnorm = dummySed.calcFluxNorm(magNorm, self._normalizing_bandpass) dummySed.multiplyFluxNorm(fnorm) magList = bandpassDict.magListForSed(dummySed, indices=indices) self._ssmMagDict[magTag] = magList self._ssmMagNormDict[sedName] = magNorm else: dmag = magNorm - self._ssmMagNormDict[sedName] magList = self._ssmMagDict[magTag] + dmag magListOut.append(magList) return np.array(magListOut).transpose()
seds = glob.glob('*.dat') seds.remove('harris_V.dat') print 'Calculating colors for seds: \n', seds writestring = 'Sed ' for f in filterlist: writestring += 'V-%s ' %(f) print writestring fig = plt.figure() for s in seds: sed = Sed() sed.readSED_flambda(s) sname = s.replace('.dat', '') vmag = sed.calcMag(harrisV) colors = {} writestring = '%s ' %(sname) for f in filterlist: mag = sed.calcMag(lsst[f]) colors[f] = vmag - mag writestring += '%.3f ' %(colors[f]) print writestring plotPointColor = np.random.rand(3) plt.plot(colors['g'], colors['r'], linestyle='', marker='o', color=plotPointColor, label='%s' %(sname)) pylab.annotate(sname, colors['g']+0.005, colors['r']+0.005, color=plotPointColor) plt.xlabel('V-g') plt.ylabel('V-r')
def get_TotalMags(result, bandpasses=('u','g','r','i','z','y')): datadir = os.environ.get("SIMS_SED_LIBRARY_DIR") tpath = os.getenv('LSST_THROUGHPUTS_DEFAULT') bands = {"u":None, "g":None, "r":None, "i":None, "z":None, "y":None} for k in bands: bands[k] = Bandpass() bands[k].readThroughput(os.path.join(tpath, "total_%s.dat"%k)) # Set up phi, the wavelength-normalized system response for each filter, # for each bandpass for manyMagCalc method. bplist = [] for f in ['u','g','r','i','z','y']: bands[f].sbTophi() bplist.append(bands[f]) ids = result['galid'] diskfile = result['sedFilenameDisk'] bulgefile = result['sedFilenameBulge'] agnfile = result['sedFilenameAgn'] diskmn = result['magNormDisk'] bulgemn = result['magNormBulge'] agnmn = result['magNormAgn'] bulgeAv = result['internalAvBulge'] diskAv = result['internalAvDisk'] redshift = result['redshift'] imsimband = Bandpass() imsimband.imsimBandpass() sedDict = {} retMags = dict([(k, []) for k in bands]) a_int = None b_int = None tmpwavelen = None for id, df, dm, dav, bf, bm, bav, af, am, z in zip(ids, diskfile, diskmn, diskAv, bulgefile, bulgemn, bulgeAv, agnfile, agnmn, redshift): tmpflux = None for comp in ((df, dm, dav, 'galaxySED', False), (bf, bm, bav, 'galaxySED', False), (af, am, None, 'agnSED', True)): #Zero out the AGN contribution #for comp in ((df, dm, dav, 'galaxySED', False), (bf, bm, bav, 'galaxySED', False), (af, 99.99, None, 'agnSED', True)): if not comp[0] == u'None': if sedDict.has_key(comp[0]): sed = copy.deepcopy(sedDict[comp[0]]) else: sed = Sed() print os.path.join(datadir,comp[3],comp[0]) sed.readSED_flambda(os.path.join(datadir,comp[3],comp[0])) if comp[4]: sed.resampleSED(wavelen_match=tmpwavelen) sedDict[comp[0]] = sed if a_int is None: phiarray, dlambda = sed.setupPhiArray(bplist) a_int, b_int = sed.setupCCMab() #Careful, this assumes that a disk or bulge sed is read #before any agn sed tmpwavelen = sed.wavelen fNorm = sed.calcFluxNorm(comp[1], imsimband) sed.multiplyFluxNorm(fNorm) #I guess this assumes rv=3.1?? if comp[2]: sed.addCCMDust(a_int, b_int, A_v=comp[2]) wavelenArr=sed.wavelen if tmpflux is None: tmpflux = sed.flambda else: tmpflux += sed.flambda newgal = Sed(wavelen=wavelenArr, flambda=tmpflux) #a_mw, b_mw = sed.setupCCMab() #sed.addCCMDust(a_mw, b_mw, A_v=mwav) newgal.redshiftSED(z, dimming=True) newgal.resampleSED(wavelen_match=bplist[0].wavelen) newgal.flambdaTofnu() mags = newgal.manyMagCalc(phiarray, dlambda) for i,k in enumerate(['u','g','r','i','z','y']): retMags[k].append(mags[i]) return retMags
# Note that Bandpass and Sed are set up for NANOMETERS units on input data # Instantiate a Bandpass object to hold the throughput information rband = Bandpass() # Read the bandpass data file into that object - # (note exampleBandpass.dat contains THROUGHPUT information, not PHI) bpfile = 'exampleBandpass.dat' rband.readThroughput(bpfile) # Instantiate a Sed object to hold the spectral energy distribution information star = Sed() # Read the Sed data file into that object - # (note that exampleSED.dat contains wavelength/F_lambda .. but is possible to also # read in wavelength/F_nu data using readSED_fnu) sedfile = 'exampleSED.dat' star.readSED_flambda(sedfile) print "" print "Read %s into Bandpass and %s into Sed." %(bpfile, sedfile) # Simply calculate the magnitude of this source in the bandpass. mag = star.calcMag(rband) print "" print "Without any scaling of the SED, the magnitude is %.4f" %(mag) # That was probably pretty small, right? Maybe we actually know what # magnitude we expect this source to have in this bandpass, and then want to scale # the SED to that appropriate magnitude (and then calculate the magnitudes once it's # scaled properly, in other bandpasses).