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 test_norm(self): """ Test that the special test case getImsimFluxNorm returns the same value as calling calcFluxNorm actually passing in the imsim Bandpass """ bp = Bandpass() bp.imsimBandpass() rng = np.random.RandomState(1123) wavelen = np.arange(300.0, 2000.0, 0.17) for ix in range(10): flux = rng.random_sample(len(wavelen))*100.0 sed = Sed() sed.setSED(wavelen=wavelen, flambda=flux) magmatch = rng.random_sample()*5.0 + 10.0 control = sed.calcFluxNorm(magmatch, bp) test = getImsimFluxNorm(sed, magmatch) # something about how interpolation is done in Sed means # that the values don't come out exactly equal. They come # out equal to 8 seignificant digits, though. self.assertEqual(control, test)
def magListForSed(self, sedobj, indices=None): """ Return a list of magnitudes for a single Sed object. @param [in] sedobj is an Sed object. Its wavelength grid can be arbitrary. If necessary, a copy will be created and resampled onto the wavelength grid of the Bandpasses before magnitudes are calculated. The original Sed will be unchanged. @param [in] indices is an optional list of indices indicating which bandpasses to actually calculate magnitudes for. Other magnitudes will be listed as numpy.NaN (i.e. this method will return as many magnitudes as were loaded with the loadBandpassesFromFiles methods; it will just return numpy.NaN for magnitudes you did not actually ask for) @param [out] magList is a list of magnitudes in the bandpasses stored in this BandpassDict """ if sedobj.wavelen is not None: # If the Sed's wavelength grid agrees with self._wavelen_match to one part in # 10^6, just use the Sed as-is. Otherwise, copy it and resample it onto # self._wavelen_match if sedobj._needResample(wavelen_match=self._wavelen_match): dummySed = Sed(wavelen=sedobj.wavelen, flambda=sedobj.flambda) dummySed.resampleSED(force=True, wavelen_match=self._bandpassDict.values()[0].wavelen) else: dummySed = sedobj return numpy.array(self._magListForSed(dummySed, indices=indices)) else: return numpy.array([numpy.NaN]*len(self._bandpassDict))
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 mCalcs(airmass, bandName, ra, dec, expMJD, FWHMeff, hwbpdict, photparams=None, sm=None): """ sm : """ if photparams is None: photparams = PhotometricParameters() if sm is None: sm = SkyModel(observatory='LSST', mags=False, preciseAltAz=True) # Obtain full sky transmission at airmass # Note that this method is not interpolating but choosing the atmospheric transmission from # Modtran simulations of the closest airmass in a sequence of np.arange(1., 2.51, 0.1) fname = atmTransName(airmass) print(fname) atmTrans = np.loadtxt(fname) wave, trans = hwbpdict[bandName].multiplyThroughputs(atmTrans[:, 0], atmTrans[:, 1]) bp = Bandpass(wavelen=wave, sb=trans) # Set the observing condition sm.setRaDecMjd(lon=[ra], lat=[dec], filterNames=[bandName], mjd=expMJD, degrees=False, azAlt=False) # Get the sky sed wave, spec = sm.returnWaveSpec() sed = Sed(wavelen=wave, flambda=spec[0]) sed.writeSED('skySED_laptop.csv') m5 = calcM5(sed, bp, hwbpdict[bandName], photparams, FWHMeff) # Get the sky magnitude only in the band concerned m = sm.returnMags(bandpasses=hwbpdict)[bandName][0] return m5, m
def setUp(self): starFileName = os.path.join(lsst.utils.getPackageDir("sims_sed_library"), "starSED") starFileName = os.path.join(starFileName, "kurucz", "km20_5750.fits_g40_5790.gz") starName = os.path.join(lsst.utils.getPackageDir("sims_sed_library"), starFileName) self.starSED = Sed() self.starSED.readSED_flambda(starName) imsimband = Bandpass() imsimband.imsimBandpass() fNorm = self.starSED.calcFluxNorm(22.0, imsimband) self.starSED.multiplyFluxNorm(fNorm) hardwareDir = os.path.join(lsst.utils.getPackageDir("throughputs"), "baseline") componentList = ["detector.dat", "m1.dat", "m2.dat", "m3.dat", "lens1.dat", "lens2.dat", "lens3.dat"] self.skySed = Sed() self.skySed.readSED_flambda(os.path.join(hardwareDir, "darksky.dat")) totalNameList = ["total_u.dat", "total_g.dat", "total_r.dat", "total_i.dat", "total_z.dat", "total_y.dat"] self.bpList = [] self.hardwareList = [] for name in totalNameList: dummy = Bandpass() dummy.readThroughput(os.path.join(hardwareDir, name)) self.bpList.append(dummy) dummy = Bandpass() hardwareNameList = [os.path.join(hardwareDir, name)] for component in componentList: hardwareNameList.append(os.path.join(hardwareDir, component)) dummy.readThroughputList(hardwareNameList) self.hardwareList.append(dummy) self.filterNameList = ["u", "g", "r", "i", "z", "y"]
def 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 testRedshiftName(self): testsed = Sed(self.testsed.wavelen, self.testsed.flambda, name=self.testsed.name) redshift = .2 testsed.redshiftSED(redshift=redshift) newname = testsed.name + '_Z' + '%.2f' % (redshift) testsed.name = newname self.assertEqual(testsed.name, newname)
def calcBasicColors(self, sedList, bandpassDict, makeCopy = False): """ This will calculate a set of colors from a list of SED objects when there is no need to redshift the SEDs. @param [in] sedList is the set of spectral objects from the models SEDs provided by loaders in rgStar or rgGalaxy. NOTE: Since this uses photometryBase.manyMagCalc_list the SED objects will be changed. @param [in] bandpassDict is a BandpassDict class instance with the Bandpasses set to those for the magnitudes given for the catalog object @param [in] makeCopy indicates whether or not to operate on copies of the SED objects in sedList since this method will change the wavelength grid. @param [out] modelColors is the set of colors in the Bandpasses provided for the given sedList. """ modelColors = [] for specObj in sedList: if makeCopy==True: fileSED = Sed() fileSED.setSED(wavelen = specObj.wavelen, flambda = specObj.flambda) sEDMags = bandpassDict.magListForSed(fileSED) else: sEDMags = bandpassDict.magListForSed(specObj) colorInfo = [] for filtNum in range(0, len(bandpassDict)-1): colorInfo.append(sEDMags[filtNum] - sEDMags[filtNum+1]) modelColors.append(colorInfo) return modelColors
def returnMags(self, bandpass=None): """ Convert the computed spectra to magnitudes using the supplied bandpasses, or, if self.mags=True, just return the mags in the LSST filters If mags=True when initialized, return mags returns an structured array with dtype names u,g,r,i,z,y. """ if self.mags: if bandpass: warnings.warn('Ignoring set bandpasses and returning LSST ugrizy.') mags = -2.5*np.log10(self.spec)+np.log10(3631.) # Mask out high airmass mags[self.mask] *= np.nan # Convert to a structured array mags = np.core.records.fromarrays(mags.transpose(), names='u,g,r,i,z,y', formats='float,'*6) else: mags = np.zeros(self.npts, dtype=float)-666 tempSed = Sed() isThrough = np.where(bandpass.sb > 0) minWave = bandpass.wavelen[isThrough].min() maxWave = bandpass.wavelen[isThrough].max() inBand = np.where((self.wave >= minWave) & (self.wave <= maxWave)) for i, ra in enumerate(self.ra): # Check that there is flux in the band, otherwise calcMag fails if np.max(self.spec[i, inBand]) > 0: tempSed.setSED(self.wave, flambda=self.spec[i, :]) mags[i] = tempSed.calcMag(bandpass) # Mask out high airmass mags[self.mask] *= np.nan return mags
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 setM5(m5target, skysed, totalBandpass, hardware, photParams, FWHMeff = None): """ Take an SED representing the sky and normalize it so that m5 (the magnitude at which an object is detected in this bandpass at 5-sigma) is set to some specified value. The 5-sigma limiting magnitude (m5) for an observation is determined by a combination of the telescope and camera parameters (such as diameter of the mirrors and the readnoise) together with the sky background. This method (setM5) scales a provided sky background Sed so that an observation would have a target m5 value, for the provided hardware parameters. Using the resulting Sed in the 'calcM5' method will return this target value for m5. @param [in] the desired value of m5 @param [in] skysed is an instantiation of the Sed class representing sky emission @param [in] totalBandpass is an instantiation of the Bandpass class representing the total throughput of the telescope (instrumentation plus atmosphere) @param [in] hardware is an instantiation of the Bandpass class representing the throughput due solely to instrumentation. @param [in] photParams is an instantiation of the PhotometricParameters class that carries details about the photometric response of the telescope. @param [in] FWHMeff in arcseconds @param [out] returns an instantiation of the Sed class that is the skysed renormalized so that m5 has the desired value. Note that the returned SED will be renormalized such that calling the method self.calcADU(hardwareBandpass) on it will yield the number of counts per square arcsecond in a given bandpass. """ #This is based on the LSST SNR document (v1.2, May 2010) #www.astro.washington.edu/users/ivezic/Astr511/LSST_SNRdoc.pdf if FWHMeff is None: FWHMeff = LSSTdefaults().FWHMeff('r') skyCountsTarget = calcSkyCountsPerPixelForM5(m5target, totalBandpass, FWHMeff=FWHMeff, photParams=photParams) skySedOut = Sed(wavelen=numpy.copy(skysed.wavelen), flambda=numpy.copy(skysed.flambda)) skyCounts = skySedOut.calcADU(hardware, photParams=photParams) \ * photParams.platescale * photParams.platescale skySedOut.multiplyFluxNorm(skyCountsTarget/skyCounts) return skySedOut
def 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 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 testFluxListForSedList(self): """ Test that fluxListForSedList calculates the correct fluxes """ nBandpasses = 7 bpNameList, bpList = self.getListOfBandpasses(nBandpasses) testBpDict = BandpassDict(bpList, bpNameList) nSed = 20 sedNameList = self.getListOfSedNames(nSed) magNormList = self.rng.random_sample(nSed)*5.0 + 15.0 internalAvList = self.rng.random_sample(nSed)*0.3 + 0.1 redshiftList = self.rng.random_sample(nSed)*5.0 galacticAvList = self.rng.random_sample(nSed)*0.3 + 0.1 # first, test on an SedList without a wavelenMatch testSedList = SedList(sedNameList, magNormList, fileDir=self.sedDir, internalAvList=internalAvList, redshiftList=redshiftList, galacticAvList=galacticAvList) fluxList = testBpDict.fluxListForSedList(testSedList) self.assertEqual(fluxList.shape[0], nSed) self.assertEqual(fluxList.shape[1], nBandpasses) for ix, sedObj in enumerate(testSedList): dummySed = Sed(wavelen=copy.deepcopy(sedObj.wavelen), flambda=copy.deepcopy(sedObj.flambda)) for iy, bp in enumerate(testBpDict): flux = dummySed.calcFlux(bpList[iy]) self.assertAlmostEqual(flux/fluxList[ix][iy], 1.0, 2) # now use wavelenMatch testSedList = SedList(sedNameList, magNormList, fileDir=self.sedDir, internalAvList=internalAvList, redshiftList=redshiftList, galacticAvList=galacticAvList, wavelenMatch=testBpDict.wavelenMatch) fluxList = testBpDict.fluxListForSedList(testSedList) self.assertEqual(fluxList.shape[0], nSed) self.assertEqual(fluxList.shape[1], nBandpasses) for ix, sedObj in enumerate(testSedList): dummySed = Sed(wavelen=copy.deepcopy(sedObj.wavelen), flambda=copy.deepcopy(sedObj.flambda)) for iy, bp in enumerate(testBpDict): flux = dummySed.calcFlux(bpList[iy]) self.assertAlmostEqual(flux/fluxList[ix][iy], 1.0, 2)
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 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 testPhiArray(self): """ Test that the phi array is correctly calculated by BandpassDict upon construction. """ for nBp in range(3, 10, 1): nameList, bpList = self.getListOfBandpasses(nBp) testDict = BandpassDict(bpList, nameList) dummySed = Sed() controlPhi, controlWavelenStep = dummySed.setupPhiArray(bpList) numpy.testing.assert_array_almost_equal(controlPhi, testDict.phiArray, 19) self.assertAlmostEqual(controlWavelenStep, testDict.wavelenStep, 10)
def testSedBandpassMatch(self): """Test errors when bandpass and sed do not completely overlap in wavelength range.""" # Test case where they do match (no error message) sedwavelen = np.arange(self.wmin, self.wmax+.5, 1) sedflambda = np.ones(len(sedwavelen)) testsed = Sed(wavelen=sedwavelen, flambda=sedflambda) print('') # Test that no warning is made. with warnings.catch_warnings(record=True) as wa: w, f = testsed.resampleSED(wavelen_match=self.testbandpass.wavelen, wavelen=testsed.wavelen, flux=testsed.flambda) self.assertEqual(len(wa), 0) np.testing.assert_equal(w, testsed.wavelen) np.testing.assert_equal(f, testsed.flambda) # Test that warning is given for non-overlap at either top or bottom end of wavelength range. sedwavelen = np.arange(self.wmin, self.wmax - 50, 1) sedflambda = np.ones(len(sedwavelen)) testsed = Sed(wavelen=sedwavelen, flambda=sedflambda) with warnings.catch_warnings(record=True) as wa: testsed.resampleSED(wavelen_match=self.testbandpass.wavelen) self.assertEqual(len(wa), 1) self.assertIn('non-overlap', str(wa[-1].message)) np.testing.assert_equal(testsed.flambda[-1:], np.NaN) sedwavelen = np.arange(self.wmin+50, self.wmax, 1) sedflambda = np.ones(len(sedwavelen)) testsed = Sed(wavelen=sedwavelen, flambda=sedflambda) with warnings.catch_warnings(record=True) as wa: testsed.resampleSED(wavelen_match=self.testbandpass.wavelen) self.assertEqual(len(wa), 1) self.assertIn('non-overlap', str(wa[-1].message)) np.testing.assert_equal(testsed.flambda[0], np.NaN) np.testing.assert_equal(testsed.flambda[49], np.NaN)
def testMagArrayForSedList(self): """ Test that magArrayForSedList calculates the correct magnitude """ nBandpasses = 7 bpNameList, bpList = self.getListOfBandpasses(nBandpasses) testBpDict = BandpassDict(bpList, bpNameList) nSed = 20 sedNameList = self.getListOfSedNames(nSed) magNormList = self.rng.random_sample(nSed)*5.0 + 15.0 internalAvList = self.rng.random_sample(nSed)*0.3 + 0.1 redshiftList = self.rng.random_sample(nSed)*5.0 galacticAvList = self.rng.random_sample(nSed)*0.3 + 0.1 # first, test on an SedList without a wavelenMatch testSedList = SedList(sedNameList, magNormList, fileDir=self.sedDir, internalAvList=internalAvList, redshiftList=redshiftList, galacticAvList=galacticAvList) magArray = testBpDict.magArrayForSedList(testSedList) for ix, sedObj in enumerate(testSedList): dummySed = Sed(wavelen=copy.deepcopy(sedObj.wavelen), flambda=copy.deepcopy(sedObj.flambda)) for iy, bp in enumerate(bpNameList): mag = dummySed.calcMag(bpList[iy]) self.assertAlmostEqual(mag, magArray[bp][ix], 2) # now use wavelenMatch testSedList = SedList(sedNameList, magNormList, fileDir=self.sedDir, internalAvList=internalAvList, redshiftList=redshiftList, galacticAvList=galacticAvList, wavelenMatch=testBpDict.wavelenMatch) magArray = testBpDict.magArrayForSedList(testSedList) for ix, sedObj in enumerate(testSedList): dummySed = Sed(wavelen=copy.deepcopy(sedObj.wavelen), flambda=copy.deepcopy(sedObj.flambda)) for iy, bp in enumerate(bpNameList): mag = dummySed.calcMag(bpList[iy]) self.assertAlmostEqual(mag, magArray[bp][ix], 2)
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 test_mags_vs_flux(self): """ Verify that the relationship between Sed.calcMag() and Sed.calcFlux() is as expected """ wavelen = np.arange(100.0, 1500.0, 1.0) flambda = np.exp(-0.5*np.power((wavelen-500.0)/100.0,2)) sb = (wavelen-100.0)/1400.0 ss = Sed(wavelen=wavelen, flambda=flambda) bp = Bandpass(wavelen=wavelen, sb=sb) mag = ss.calcMag(bp) flux = ss.calcFlux(bp) self.assertAlmostEqual(ss.magFromFlux(flux)/mag, 1.0, 10) self.assertAlmostEqual(ss.fluxFromMag(mag)/flux, 1.0, 10)
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 testFluxDictForSed(self): """ Test that fluxDictForSed calculates the correct fluxes """ wavelen = numpy.arange(10.0,2000.0,1.0) flux = (wavelen*2.0-5.0)*1.0e-6 spectrum = Sed(wavelen=wavelen, flambda=flux) for nBp in range(3, 10, 1): nameList, bpList = self.getListOfBandpasses(nBp) testDict = BandpassDict(bpList, nameList) self.assertFalse(len(testDict.values()[0].wavelen)==len(spectrum.wavelen)) fluxDict = testDict.fluxDictForSed(spectrum) for ix, (name, bp) in enumerate(zip(nameList, bpList)): fluxControl = spectrum.calcFlux(bp) self.assertAlmostEqual(fluxDict[name]/fluxControl, 1.0, 2)
def __init__(self, bandpassList, bandpassNameList): """ @param [in] bandpassList is a list of Bandpass instantiations @param [in] bandpassNameList is a list of tags to be associated with those Bandpasses. These will be used as keys for the BandpassDict. """ self._bandpassDict = OrderedDict() for bandpassName, bandpass in zip(bandpassNameList, bandpassList): if bandpassName in self._bandpassDict: raise RuntimeError("The bandpass %s occurs twice in your input " % bandpassName \ + "to BandpassDict") self._bandpassDict[bandpassName] = copy.deepcopy(bandpass) dummySed = Sed() self._phiArray, self._wavelenStep = dummySed.setupPhiArray(self._bandpassDict.values()) self._wavelen_match = self._bandpassDict.values()[0].wavelen
def computeMags(self, bandpass=None): """After the spectra have been computed, optionally convert to mags""" if self.mags: mags = -2.5*np.log10(self.spec)+np.log10(3631.) else: mags = np.zeros(self.npts, dtype=float)-666 tempSed = Sed() isThrough = np.where(bandpass.sb > 0) minWave = bandpass.wavelen[isThrough].min() maxWave = bandpass.wavelen[isThrough].max() inBand = np.where( (self.wave >= minWave) & (self.wave <= maxWave)) for i, ra in enumerate(self.ra): if np.max(self.spec[i,inBand]) > 0: tempSed.setSED(self.wave, flambda=self.spec[i,:]) # Need to try/except because the spectra might be zero in the filter # XXX-upgrade this to check if it's zero mags[i] = tempSed.calcMag(bandpass) return mags
def testMagListForSed(self): """ Test that magListForSed calculates the correct magnitude """ wavelen = numpy.arange(10.0,2000.0,1.0) flux = (wavelen*2.0-5.0)*1.0e-6 spectrum = Sed(wavelen=wavelen, flambda=flux) for nBp in range(3, 10, 1): nameList, bpList = self.getListOfBandpasses(nBp) testDict = BandpassDict(bpList, nameList) self.assertFalse(len(testDict.values()[0].wavelen)==len(spectrum.wavelen)) magList = testDict.magListForSed(spectrum) for ix, (name, bp, magTest) in enumerate(zip(nameList, bpList, magList)): magControl = spectrum.calcMag(bp) self.assertAlmostEqual(magTest, magControl, 5)
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 returnMags(self, bandpasses=None): """ Convert the computed spectra to a magnitude using the supplied bandpass, or, if self.mags=True, return the mags in the LSST filters If mags=True when initialized, return mags returns an structured array with dtype names u,g,r,i,z,y. bandpasses: optional dictionary with bandpass name keys and bandpass object values. """ if self.azs is None: raise ValueError('No coordinates set. Use setRaDecMjd, setRaDecAltAzMjd, or setParams methods before calling returnMags.') if self.mags: if bandpasses: warnings.warn('Ignoring set bandpasses and returning LSST ugrizy.') mags = -2.5*np.log10(self.spec)+np.log10(3631.) # Mask out high airmass mags[self.mask] *= np.nan mags = mags.swapaxes(0, 1) magsBack = {} for i, f in enumerate(self.filterNames): magsBack[f] = mags[i] else: magsBack = {} for key in bandpasses: mags = np.zeros(self.npts, dtype=float)-666 tempSed = Sed() isThrough = np.where(bandpasses[key].sb > 0) minWave = bandpasses[key].wavelen[isThrough].min() maxWave = bandpasses[key].wavelen[isThrough].max() inBand = np.where((self.wave >= minWave) & (self.wave <= maxWave)) for i, ra in enumerate(self.ra): # Check that there is flux in the band, otherwise calcMag fails if np.max(self.spec[i, inBand]) > 0: tempSed.setSED(self.wave, flambda=self.spec[i, :]) mags[i] = tempSed.calcMag(bandpasses[key]) # Mask out high airmass mags[self.mask] *= np.nan magsBack[key] = mags return magsBack
def _calcColors(self, sedname='C.dat', sedDir=None): """ Calculate the colors for a moving object with sed 'sedname'. """ # Do we need to read in the LSST bandpasses? try: self.lsst except AttributeError: envvar = 'LSST_THROUGHPUTS_BASELINE' filterdir = os.getenv(envvar) if filterdir is None: raise RuntimeError( 'Cannot find directory for throughput curves. Set env var %s' % (envvar)) self.filterlist = ('u', 'g', 'r', 'i', 'z', 'y') self.lsst = {} for f in self.filterlist: self.lsst[f] = Bandpass() self.lsst[f].readThroughput( os.path.join(filterdir, 'total_' + f + '.dat')) self.seddir = sedDir if self.seddir is None: self.seddir = os.path.join(getPackageDir('SIMS_MOVINGOBJECTS'), 'data') self.vband = Bandpass() self.vband.readThroughput(os.path.join(self.seddir, '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(os.path.join(self.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 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 calcColors(self, sedname='C.dat', sedDir=None): """ Calculate the colors for a given SED, store the result. 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. """ # See if the sed's colors are in memory already. 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
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 sprinkle(self): # Define a list that we can write out to a text file lenslines = [] # For each galaxy in the catsim catalog updated_catalog = self.catalog.copy() # print("Running sprinkler. Catalog Length: ", len(self.catalog)) for rowNum, row in enumerate(self.catalog): # if rowNum == 100 or rowNum % 100000==0: # print("Gone through ", rowNum, " lines of catalog.") if not np.isnan(row[self.defs_dict['galaxyAgn_magNorm']]): candidates = self.find_lens_candidates( row[self.defs_dict['galaxyAgn_redshift']], row[self.defs_dict['galaxyAgn_magNorm']]) #varString = json.loads(row[self.defs_dict['galaxyAgn_varParamStr']]) # varString[self.defs_dict['pars']]['t0_mjd'] = 59300.0 #row[self.defs_dict['galaxyAgn_varParamStr']] = json.dumps(varString) np.random.seed(row[self.defs_dict['galtileid']] % (2 ^ 32 - 1)) pick_value = np.random.uniform() # If there aren't any lensed sources at this redshift from OM10 move on the next object if (((len(candidates) > 0) and (pick_value <= self.density_param) and (self.cached_sprinkling is False)) | ((self.cached_sprinkling is True) and (row[self.defs_dict['galtileid']] in self.agn_cache['galtileid'].values))): # Randomly choose one the lens systems # (can decide with or without replacement) # Sort first to make sure the same choice is made every time if self.cached_sprinkling is True: twinkles_sys_cache = self.agn_cache.query( 'galtileid == %i' % row[self.defs_dict['galtileid']] )['twinkles_system'].values[0] newlens = self.lenscat[np.where( self.lenscat['twinklesId'] == twinkles_sys_cache) [0]][0] else: candidates = candidates[np.argsort( candidates['twinklesId'])] newlens = np.random.choice(candidates) # Append the lens galaxy # For each image, append the lens images for i in range(newlens['NIMG']): lensrow = row.copy() # XIMG and YIMG are in arcseconds # raPhSim and decPhoSim are in radians #Shift all parts of the lensed object, not just its agn part for lensPart in [ 'galaxyBulge', 'galaxyDisk', 'galaxyAgn' ]: lens_ra = lensrow[self.defs_dict[str(lensPart + '_raJ2000')]] lens_dec = lensrow[self.defs_dict[str( lensPart + '_decJ2000')]] delta_ra = np.radians( newlens['XIMG'][i] / 3600.0) / np.cos(lens_dec) delta_dec = np.radians(newlens['YIMG'][i] / 3600.0) lensrow[self.defs_dict[str( lensPart + '_raJ2000')]] = lens_ra + delta_ra lensrow[self.defs_dict[ str(lensPart + '_decJ2000')]] = lens_dec + delta_dec mag_adjust = 2.5 * np.log10(np.abs(newlens['MAG'][i])) lensrow[ self.defs_dict['galaxyAgn_magNorm']] -= mag_adjust varString = json.loads( lensrow[self.defs_dict['galaxyAgn_varParamStr']]) varString[self.defs_dict['pars']]['t0Delay'] = newlens[ 'DELAY'][i] varString[self.defs_dict[ 'varMethodName']] = 'applyAgnTimeDelay' lensrow[self.defs_dict[ 'galaxyAgn_varParamStr']] = json.dumps(varString) lensrow[self.defs_dict['galaxyDisk_majorAxis']] = 0.0 lensrow[self.defs_dict['galaxyDisk_minorAxis']] = 0.0 lensrow[ self.defs_dict['galaxyDisk_positionAngle']] = 0.0 lensrow[self.defs_dict['galaxyDisk_internalAv']] = 0.0 lensrow[self.defs_dict[ 'galaxyDisk_magNorm']] = 999. #np.nan To be fixed post run1.1 lensrow[ self.defs_dict['galaxyDisk_sedFilename']] = None lensrow[self.defs_dict['galaxyBulge_majorAxis']] = 0.0 lensrow[self.defs_dict['galaxyBulge_minorAxis']] = 0.0 lensrow[ self.defs_dict['galaxyBulge_positionAngle']] = 0.0 lensrow[self.defs_dict['galaxyBulge_internalAv']] = 0.0 lensrow[self.defs_dict[ 'galaxyBulge_magNorm']] = 999. #np.nan To be fixed post run1.1 lensrow[ self.defs_dict['galaxyBulge_sedFilename']] = None lensrow[self.defs_dict[ 'galaxyBulge_redshift']] = newlens['ZSRC'] lensrow[self.defs_dict[ 'galaxyDisk_redshift']] = newlens['ZSRC'] lensrow[self.defs_dict[ 'galaxyAgn_redshift']] = newlens['ZSRC'] #To get back twinklesID in lens catalog from phosim catalog id number #just use np.right_shift(phosimID-28, 10). Take the floor of the last #3 numbers to get twinklesID in the twinkles lens catalog and the remainder is #the image number minus 1. lensrow[self.defs_dict['galtileid']] = ( lensrow[self.defs_dict['galtileid']] * 10000 + newlens['twinklesId'] * 4 + i) updated_catalog = np.append(updated_catalog, lensrow) #Now manipulate original entry to be the lens galaxy with desired properties #Start by deleting Disk and AGN properties if not np.isnan(row[self.defs_dict['galaxyDisk_magNorm']]): row[self.defs_dict['galaxyDisk_majorAxis']] = 0.0 row[self.defs_dict['galaxyDisk_minorAxis']] = 0.0 row[self.defs_dict['galaxyDisk_positionAngle']] = 0.0 row[self.defs_dict['galaxyDisk_internalAv']] = 0.0 row[self.defs_dict[ 'galaxyDisk_magNorm']] = 999. #np.nan To be fixed post run1.1 row[self.defs_dict['galaxyDisk_sedFilename']] = None row[self.defs_dict[ 'galaxyAgn_magNorm']] = None #np.nan To be fixed post run1.1 row[self.defs_dict[ 'galaxyDisk_magNorm']] = 999. # To be fixed in run1.1 row[self.defs_dict['galaxyAgn_sedFilename']] = None #Now insert desired Bulge properties row[self.defs_dict['galaxyBulge_sedFilename']] = newlens[ 'lens_sed'] row[self. defs_dict['galaxyBulge_redshift']] = newlens['ZLENS'] row[self. defs_dict['galaxyDisk_redshift']] = newlens['ZLENS'] row[self. defs_dict['galaxyAgn_redshift']] = newlens['ZLENS'] row_lens_sed = Sed() row_lens_sed.readSED_flambda( str(self.galDir + newlens['lens_sed'])) row_lens_sed.redshiftSED(newlens['ZLENS'], dimming=True) row[self.defs_dict['galaxyBulge_magNorm']] = matchBase( ).calcMagNorm( [newlens['APMAG_I']], row_lens_sed, self.bandpassDict) #Changed from i band to imsimband row[self.defs_dict[ 'galaxyBulge_majorAxis']] = radiansFromArcsec( newlens['REFF'] / np.sqrt(1 - newlens['ELLIP'])) row[self.defs_dict[ 'galaxyBulge_minorAxis']] = radiansFromArcsec( newlens['REFF'] * np.sqrt(1 - newlens['ELLIP'])) #Convert orientation angle to west of north from east of north by *-1.0 and convert to radians row[self.defs_dict['galaxyBulge_positionAngle']] = newlens[ 'PHIE'] * (-1.0) * np.pi / 180.0 #Replace original entry with new entry updated_catalog[rowNum] = row else: if self.cached_sprinkling is True: if row[self.defs_dict['galtileid']] in self.sne_cache[ 'galtileid'].values: use_system = self.sne_cache.query( 'galtileid == %i' % row[self.defs_dict['galtileid']] )['twinkles_system'].values use_df = self.sne_catalog.query( 'twinkles_sysno == %i' % use_system) self.used_systems.append(use_system) else: continue else: lens_sne_candidates = self.find_sne_lens_candidates( row[self.defs_dict['galaxyDisk_redshift']]) candidate_sysno = np.unique( lens_sne_candidates['twinkles_sysno']) num_candidates = len(candidate_sysno) if num_candidates == 0: continue used_already = np.array([ sys_num in self.used_systems for sys_num in candidate_sysno ]) unused_sysno = candidate_sysno[~used_already] if len(unused_sysno) == 0: continue np.random.seed(row[self.defs_dict['galtileid']] % (2 ^ 32 - 1)) use_system = np.random.choice(unused_sysno) use_df = self.sne_catalog.query('twinkles_sysno == %i' % use_system) for i in range(len(use_df)): lensrow = row.copy() for lensPart in ['galaxyBulge', 'galaxyDisk', 'galaxyAgn']: lens_ra = lensrow[self.defs_dict[str(lensPart + '_raJ2000')]] lens_dec = lensrow[self.defs_dict[str(lensPart + '_decJ2000')]] delta_ra = np.radians( use_df['x'].iloc[i] / 3600.0) / np.cos(lens_dec) delta_dec = np.radians(use_df['y'].iloc[i] / 3600.0) lensrow[self.defs_dict[str( lensPart + '_raJ2000')]] = lens_ra + delta_ra lensrow[self.defs_dict[str( lensPart + '_decJ2000')]] = lens_dec + delta_dec # varString = json.loads(lensrow[self.defs_dict['galaxyAgn_varParamStr']]) varString = 'None' lensrow[ self.defs_dict['galaxyAgn_varParamStr']] = varString lensrow[self.defs_dict['galaxyDisk_majorAxis']] = 0.0 lensrow[self.defs_dict['galaxyDisk_minorAxis']] = 0.0 lensrow[self.defs_dict['galaxyDisk_positionAngle']] = 0.0 lensrow[self.defs_dict['galaxyDisk_internalAv']] = 0.0 lensrow[self.defs_dict[ 'galaxyDisk_magNorm']] = 999. #np.nan To be fixed post run1.1 lensrow[self.defs_dict['galaxyDisk_sedFilename']] = None lensrow[self.defs_dict['galaxyBulge_majorAxis']] = 0.0 lensrow[self.defs_dict['galaxyBulge_minorAxis']] = 0.0 lensrow[self.defs_dict['galaxyBulge_positionAngle']] = 0.0 lensrow[self.defs_dict['galaxyBulge_internalAv']] = 0.0 lensrow[self.defs_dict[ 'galaxyBulge_magNorm']] = 999. #np.nan To be fixed post run1.1 lensrow[self.defs_dict['galaxyBulge_sedFilename']] = None z_s = use_df['zs'].iloc[i] lensrow[self.defs_dict['galaxyBulge_redshift']] = z_s lensrow[self.defs_dict['galaxyDisk_redshift']] = z_s lensrow[self.defs_dict['galaxyAgn_redshift']] = z_s #To get back twinklesID in lens catalog from phosim catalog id number #just use np.right_shift(phosimID-28, 10). Take the floor of the last #3 numbers to get twinklesID in the twinkles lens catalog and the remainder is #the image number minus 1. lensrow[self.defs_dict['galtileid']] = ( lensrow[self.defs_dict['galtileid']] * 10000 + use_system * 4 + i) add_to_cat, sn_magnorm, sn_fname = self.create_sn_sed( use_df.iloc[i], lensrow[self.defs_dict['galaxyAgn_raJ2000']], lensrow[self.defs_dict['galaxyAgn_decJ2000']], self.visit_mjd) lensrow[self.defs_dict['galaxyAgn_sedFilename']] = sn_fname lensrow[self.defs_dict[ 'galaxyAgn_magNorm']] = sn_magnorm #This will need to be adjusted to proper band mag_adjust = 2.5 * np.log10(np.abs(use_df['mu'].iloc[i])) lensrow[self.defs_dict['galaxyAgn_magNorm']] -= mag_adjust if add_to_cat is True: updated_catalog = np.append(updated_catalog, lensrow) else: continue #Now manipulate original entry to be the lens galaxy with desired properties #Start by deleting Disk and AGN properties if not np.isnan(row[self.defs_dict['galaxyDisk_magNorm']]): row[self.defs_dict['galaxyDisk_majorAxis']] = 0.0 row[self.defs_dict['galaxyDisk_minorAxis']] = 0.0 row[self.defs_dict['galaxyDisk_positionAngle']] = 0.0 row[self.defs_dict['galaxyDisk_internalAv']] = 0.0 row[self.defs_dict[ 'galaxyDisk_magNorm']] = 999. #np.nan To be fixed post run1.1 row[self.defs_dict['galaxyDisk_sedFilename']] = None row[self.defs_dict[ 'galaxyAgn_magNorm']] = None #np.nan To be fixed post run1.1 row[self.defs_dict[ 'galaxyDisk_magNorm']] = 999. #To be fixed post run1.1 row[self.defs_dict['galaxyAgn_sedFilename']] = None #Now insert desired Bulge properties row[self.defs_dict['galaxyBulge_sedFilename']] = use_df[ 'lens_sed'].iloc[0] row[self. defs_dict['galaxyBulge_redshift']] = use_df['zl'].iloc[0] row[self. defs_dict['galaxyDisk_redshift']] = use_df['zl'].iloc[0] row[self. defs_dict['galaxyAgn_redshift']] = use_df['zl'].iloc[0] row[self.defs_dict['galaxyBulge_magNorm']] = use_df[ 'bulge_magnorm'].iloc[0] # row[self.defs_dict['galaxyBulge_magNorm']] = matchBase().calcMagNorm([newlens['APMAG_I']], self.LRG, self.bandpassDict) #Changed from i band to imsimband row[self. defs_dict['galaxyBulge_majorAxis']] = radiansFromArcsec( use_df['r_eff'].iloc[0] / np.sqrt(1 - use_df['e'].iloc[0])) row[self. defs_dict['galaxyBulge_minorAxis']] = radiansFromArcsec( use_df['r_eff'].iloc[0] * np.sqrt(1 - use_df['e'].iloc[0])) #Convert orientation angle to west of north from east of north by *-1.0 and convert to radians row[self.defs_dict['galaxyBulge_positionAngle']] = use_df[ 'theta_e'].iloc[0] * (-1.0) * np.pi / 180.0 #Replace original entry with new entry updated_catalog[rowNum] = row return updated_catalog
def testFlush(self): """ Test that the flush method of SedList behaves properly """ imsimBand = Bandpass() imsimBand.imsimBandpass() nSed = 10 sedNameList_0 = self.getListOfSedNames(nSed) magNormList_0 = self.rng.random_sample(nSed)*5.0 + 15.0 internalAvList_0 = self.rng.random_sample(nSed)*0.3 + 0.1 redshiftList_0 = self.rng.random_sample(nSed)*5.0 galacticAvList_0 = self.rng.random_sample(nSed)*0.3 + 0.1 wavelen_match = np.arange(300.0, 1500.0, 10.0) testList = SedList(sedNameList_0, magNormList_0, fileDir=self.sedDir, internalAvList=internalAvList_0, redshiftList=redshiftList_0, galacticAvList=galacticAvList_0, wavelenMatch=wavelen_match) self.assertEqual(len(testList), nSed) np.testing.assert_array_equal(wavelen_match, testList.wavelenMatch) for ix in range(len(sedNameList_0)): self.assertAlmostEqual(internalAvList_0[ix], testList.internalAvList[ix], 10) self.assertAlmostEqual(galacticAvList_0[ix], testList.galacticAvList[ix], 10) self.assertAlmostEqual(redshiftList_0[ix], testList.redshiftList[ix], 10) for ix, (name, norm, iav, gav, zz) in \ enumerate(zip(sedNameList_0, magNormList_0, internalAvList_0, galacticAvList_0, redshiftList_0)): sedControl = Sed() sedControl.readSED_flambda(os.path.join(self.sedDir, name+'.gz')) fnorm = sedControl.calcFluxNorm(norm, imsimBand) sedControl.multiplyFluxNorm(fnorm) a_coeff, b_coeff = sedControl.setupCCM_ab() sedControl.addDust(a_coeff, b_coeff, A_v=iav) sedControl.redshiftSED(zz, dimming=True) sedControl.resampleSED(wavelen_match=wavelen_match) a_coeff, b_coeff = sedControl.setupCCM_ab() sedControl.addDust(a_coeff, b_coeff, A_v=gav) sedTest = testList[ix] np.testing.assert_array_equal(sedControl.wavelen, sedTest.wavelen) np.testing.assert_array_equal(sedControl.flambda, sedTest.flambda) np.testing.assert_array_equal(sedControl.fnu, sedTest.fnu) testList.flush() sedNameList_1 = self.getListOfSedNames(nSed//2) magNormList_1 = self.rng.random_sample(nSed//2)*5.0 + 15.0 internalAvList_1 = self.rng.random_sample(nSed//2)*0.3 + 0.1 redshiftList_1 = self.rng.random_sample(nSed//2)*5.0 galacticAvList_1 = self.rng.random_sample(nSed//2)*0.3 + 0.1 testList.loadSedsFromList(sedNameList_1, magNormList_1, internalAvList=internalAvList_1, galacticAvList=galacticAvList_1, redshiftList=redshiftList_1) self.assertEqual(len(testList), nSed/2) self.assertEqual(len(testList.redshiftList), nSed/2) self.assertEqual(len(testList.internalAvList), nSed/2) self.assertEqual(len(testList.galacticAvList), nSed/2) np.testing.assert_array_equal(wavelen_match, testList.wavelenMatch) for ix in range(len(sedNameList_1)): self.assertAlmostEqual(internalAvList_1[ix], testList.internalAvList[ix], 10) self.assertAlmostEqual(galacticAvList_1[ix], testList.galacticAvList[ix], 10) self.assertAlmostEqual(redshiftList_1[ix], testList.redshiftList[ix], 10) for ix, (name, norm, iav, gav, zz) in \ enumerate(zip(sedNameList_1, magNormList_1, internalAvList_1, galacticAvList_1, redshiftList_1)): sedControl = Sed() sedControl.readSED_flambda(os.path.join(self.sedDir, name+'.gz')) fnorm = sedControl.calcFluxNorm(norm, imsimBand) sedControl.multiplyFluxNorm(fnorm) a_coeff, b_coeff = sedControl.setupCCM_ab() sedControl.addDust(a_coeff, b_coeff, A_v=iav) sedControl.redshiftSED(zz, dimming=True) sedControl.resampleSED(wavelen_match=wavelen_match) a_coeff, b_coeff = sedControl.setupCCM_ab() sedControl.addDust(a_coeff, b_coeff, A_v=gav) sedTest = testList[ix] np.testing.assert_array_equal(sedControl.wavelen, sedTest.wavelen) np.testing.assert_array_equal(sedControl.flambda, sedTest.flambda) np.testing.assert_array_equal(sedControl.fnu, sedTest.fnu)
def testAddingNonesToList(self): """ Test what happens if you add SEDs to an SedList that have None for one or more of the physical parameters (i.e. galacticAv, internalAv, or redshift) """ imsimBand = Bandpass() imsimBand.imsimBandpass() nSed = 10 sedNameList_0 = self.getListOfSedNames(nSed) magNormList_0 = self.rng.random_sample(nSed)*5.0 + 15.0 internalAvList_0 = self.rng.random_sample(nSed)*0.3 + 0.1 redshiftList_0 = self.rng.random_sample(nSed)*5.0 galacticAvList_0 = self.rng.random_sample(nSed)*0.3 + 0.1 wavelen_match = np.arange(300.0, 1500.0, 10.0) testList = SedList(sedNameList_0, magNormList_0, fileDir=self.sedDir, internalAvList=internalAvList_0, redshiftList=redshiftList_0, galacticAvList=galacticAvList_0, wavelenMatch=wavelen_match) sedNameList_1 = self.getListOfSedNames(nSed) magNormList_1 = list(self.rng.random_sample(nSed)*5.0 + 15.0) internalAvList_1 = list(self.rng.random_sample(nSed)*0.3 + 0.1) redshiftList_1 = list(self.rng.random_sample(nSed)*5.0) galacticAvList_1 = list(self.rng.random_sample(nSed)*0.3 + 0.1) internalAvList_1[0] = None redshiftList_1[1] = None galacticAvList_1[2] = None internalAvList_1[3] = None redshiftList_1[3] = None internalAvList_1[4] = None galacticAvList_1[4] = None redshiftList_1[5] = None galacticAvList_1[5] = None internalAvList_1[6] = None redshiftList_1[6] = None galacticAvList_1[6] = None testList.loadSedsFromList(sedNameList_1, magNormList_1, internalAvList=internalAvList_1, galacticAvList=galacticAvList_1, redshiftList=redshiftList_1) self.assertEqual(len(testList), 2*nSed) np.testing.assert_array_equal(wavelen_match, testList.wavelenMatch) for ix in range(len(sedNameList_0)): self.assertAlmostEqual(internalAvList_0[ix], testList.internalAvList[ix], 10) self.assertAlmostEqual(galacticAvList_0[ix], testList.galacticAvList[ix], 10) self.assertAlmostEqual(redshiftList_0[ix], testList.redshiftList[ix], 10) for ix in range(len(sedNameList_1)): self.assertAlmostEqual(internalAvList_1[ix], testList.internalAvList[ix+nSed], 10) self.assertAlmostEqual(galacticAvList_1[ix], testList.galacticAvList[ix+nSed], 10) self.assertAlmostEqual(redshiftList_1[ix], testList.redshiftList[ix+nSed], 10) for ix, (name, norm, iav, gav, zz) in \ enumerate(zip(sedNameList_0, magNormList_0, internalAvList_0, galacticAvList_0, redshiftList_0)): sedControl = Sed() sedControl.readSED_flambda(os.path.join(self.sedDir, name+'.gz')) fnorm = sedControl.calcFluxNorm(norm, imsimBand) sedControl.multiplyFluxNorm(fnorm) a_coeff, b_coeff = sedControl.setupCCM_ab() sedControl.addDust(a_coeff, b_coeff, A_v=iav) sedControl.redshiftSED(zz, dimming=True) sedControl.resampleSED(wavelen_match=wavelen_match) a_coeff, b_coeff = sedControl.setupCCM_ab() sedControl.addDust(a_coeff, b_coeff, A_v=gav) sedTest = testList[ix] np.testing.assert_array_equal(sedControl.wavelen, sedTest.wavelen) np.testing.assert_array_equal(sedControl.flambda, sedTest.flambda) np.testing.assert_array_equal(sedControl.fnu, sedTest.fnu) for ix, (name, norm, iav, gav, zz) in \ enumerate(zip(sedNameList_1, magNormList_1, internalAvList_1, galacticAvList_1, redshiftList_1)): sedControl = Sed() sedControl.readSED_flambda(os.path.join(self.sedDir, name+'.gz')) fnorm = sedControl.calcFluxNorm(norm, imsimBand) sedControl.multiplyFluxNorm(fnorm) if iav is not None: a_coeff, b_coeff = sedControl.setupCCM_ab() sedControl.addDust(a_coeff, b_coeff, A_v=iav) if zz is not None: sedControl.redshiftSED(zz, dimming=True) sedControl.resampleSED(wavelen_match=wavelen_match) if gav is not None: a_coeff, b_coeff = sedControl.setupCCM_ab() sedControl.addDust(a_coeff, b_coeff, A_v=gav) sedTest = testList[ix+nSed] np.testing.assert_array_equal(sedControl.wavelen, sedTest.wavelen) np.testing.assert_array_equal(sedControl.flambda, sedTest.flambda) np.testing.assert_array_equal(sedControl.fnu, sedTest.fnu)
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 __init__(self, mags=False, darkSkyMags=None, fitResults=None): """ Read the Solar spectrum into a handy object and compute mags in different filters mags: If true, only return the LSST filter magnitudes, otherwise return the full spectrum darkSkyMags = dict of the zenith dark sky values to be assumed. The twilight fits are done relative to the dark sky level. fitResults = dict of twilight parameters based on twilightFunc. Keys should be filter names. """ if darkSkyMags is None: darkSkyMags = { 'u': 22.8, 'g': 22.3, 'r': 21.2, 'i': 20.3, 'z': 19.3, 'y': 18.0, 'B': 22.35, 'G': 21.71, 'R': 21.3 } self.mags = mags dataDir = getPackageDir('sims_skybrightness_data') solarSaved = np.load(os.path.join(dataDir, 'solarSpec/solarSpec.npz')) self.solarSpec = Sed(wavelen=solarSaved['wave'], flambda=solarSaved['spec']) solarSaved.close() canonFilters = {} fnames = ['blue_canon.csv', 'green_canon.csv', 'red_canon.csv'] # Filter names, from bluest to reddest. self.filterNames = ['B', 'G', 'R'] for fname, filterName in zip(fnames, self.filterNames): bpdata = np.genfromtxt(os.path.join(dataDir, 'Canon/', fname), delimiter=', ', dtype=list( zip(['wave', 'through'], [float] * 2))) bpTemp = Bandpass() bpTemp.setBandpass(bpdata['wave'], bpdata['through']) canonFilters[filterName] = bpTemp # Tack on the LSST filters throughPath = os.path.join(getPackageDir('throughputs'), 'baseline') lsstKeys = ['u', 'g', 'r', 'i', 'z', 'y'] for key in lsstKeys: 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']) canonFilters[key] = tempB self.filterNames.append(key) # MAGIC NUMBERS from fitting the all-sky camera: # Code to generate values in sims_skybrightness/examples/fitTwiSlopesSimul.py # Which in turn uses twilight maps from sims_skybrightness/examples/buildTwilMaps.py # values are of the form: # 0: ratio of f^z_12 to f_dark^z # 1: slope of curve wrt sun alt # 2: airmass term (10^(arg[2]*(X-1))) # 3: azimuth term. # 4: zenith dark sky flux (erg/s/cm^2) # For z and y, just assuming the shape parameter fits are similar to the other bands. # Looks like the diode is not sensitive enough to detect faint sky. # Using the Patat et al 2006 I-band values for z and modeified a little for y as a temp fix. if fitResults is None: self.fitResults = { 'B': [ 7.56765633e+00, 2.29798055e+01, 2.86879956e-01, 3.01162143e-01, 2.58462036e-04 ], 'G': [ 2.38561156e+00, 2.29310648e+01, 2.97733083e-01, 3.16403197e-01, 7.29660095e-04 ], 'R': [ 1.75498017e+00, 2.22011802e+01, 2.98619033e-01, 3.28880254e-01, 3.24411056e-04 ], 'z': [2.29, 24.08, 0.3, 0.3, -666], 'y': [2.0, 24.08, 0.3, 0.3, -666] } # XXX-completely arbitrary fudge factor to make things brighter in the blue # Just copy the blue and say it's brighter. self.fitResults['u'] = [ 16., 2.29622121e+01, 2.85862729e-01, 2.99902574e-01, 2.32325117e-04 ] else: self.fitResults = fitResults # Take out any filters that don't have fit results self.filterNames = [ key for key in self.filterNames if key in self.fitResults ] self.effWave = [] self.solarMag = [] for filterName in self.filterNames: self.effWave.append(canonFilters[filterName].calcEffWavelen()[0]) self.solarMag.append( self.solarSpec.calcMag(canonFilters[filterName])) ord = np.argsort(self.effWave) self.filterNames = np.array(self.filterNames)[ord] self.effWave = np.array(self.effWave)[ord] self.solarMag = np.array(self.solarMag)[ord] # update the fit results to be zeropointed properly for key in self.fitResults: f0 = 10.**(-0.4 * (darkSkyMags[key] - np.log10(3631.))) self.fitResults[key][-1] = f0 self.solarWave = self.solarSpec.wavelen self.solarFlux = self.solarSpec.flambda # This one isn't as bad as the model grids, maybe we could get away with computing the magnitudes # in the __call__ each time. if mags: # Load up the LSST filters and convert the solarSpec.flabda and solarSpec.wavelen to fluxes throughPath = os.path.join(getPackageDir('throughputs'), 'baseline') self.lsstFilterNames = ['u', 'g', 'r', 'i', 'z', 'y'] self.lsstEquations = np.zeros( (np.size(self.lsstFilterNames), np.size(self.fitResults['B'])), dtype=float) self.lsstEffWave = [] fits = np.empty( (np.size(self.effWave), np.size(self.fitResults['B'])), dtype=float) for i, fn in enumerate(self.filterNames): fits[i, :] = self.fitResults[fn] for filtername in self.lsstFilterNames: bp = np.loadtxt(os.path.join(throughPath, 'filter_' + filtername + '.dat'), dtype=list(zip(['wave', 'trans'], [float] * 2))) tempB = Bandpass() tempB.setBandpass(bp['wave'], bp['trans']) self.lsstEffWave.append(tempB.calcEffWavelen()[0]) # Loop through the parameters and interpolate to new eff wavelengths for i in np.arange(self.lsstEquations[0, :].size): interp = InterpolatedUnivariateSpline(self.effWave, fits[:, i]) self.lsstEquations[:, i] = interp(self.lsstEffWave) # Set the dark sky flux for i, filterName in enumerate(self.lsstFilterNames): self.lsstEquations[i, -1] = 10.**( -0.4 * (darkSkyMags[filterName] - np.log10(3631.))) self.filterNameDict = {'u': 0, 'g': 1, 'r': 2, 'i': 3, 'z': 4, 'y': 5}
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_sed_library'), '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 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 __init__(self, catsim_cat, visit_mjd, specFileMap, sed_path, om10_cat='twinkles_lenses_v2.fits', sne_cat='dc2_sne_cat.csv', density_param=1., cached_sprinkling=False, agn_cache_file=None, sne_cache_file=None, defs_file=None): """ Parameters ---------- catsim_cat: catsim catalog The results array from an instance catalog. visit_mjd: float The mjd of the visit specFileMap: This will tell the instance catalog where to write the files om10_cat: optional, defaults to 'twinkles_lenses_v2.fits fits file with OM10 catalog sne_cat: optional, defaults to 'dc2_sne_cat.csv' density_param: `np.float`, optioanl, defaults to 1.0 the fraction of eligible agn objects that become lensed and should be between 0.0 and 1.0. cached_sprinkling: boolean If true then pick from a preselected list of galtileids agn_cache_file: str sne_cache_file: str defs_file: str Returns ------- updated_catalog: A new results array with lens systems added. """ twinklesDir = getPackageDir('Twinkles') om10_cat = os.path.join(twinklesDir, 'data', om10_cat) self.catalog = catsim_cat # ****** THIS ASSUMES THAT THE ENVIRONMENT VARIABLE OM10_DIR IS SET ******* lensdb = om10.DB(catalog=om10_cat, vb=False) self.lenscat = lensdb.lenses.copy() self.density_param = density_param self.bandpassDict = BandpassDict.loadTotalBandpassesFromFiles( bandpassNames=['i']) self.sne_catalog = pd.read_csv( os.path.join(twinklesDir, 'data', sne_cat)) #self.sne_catalog = self.sne_catalog.iloc[:101] ### Remove this after testing self.used_systems = [] self.visit_mjd = visit_mjd self.sn_obj = SNObject(0., 0.) self.write_dir = specFileMap.subdir_map['(^specFileGLSN)'] self.sed_path = sed_path self.cached_sprinkling = cached_sprinkling if self.cached_sprinkling is True: if ((agn_cache_file is None) | (sne_cache_file is None)): raise AttributeError( 'Must specify cache files if using cached_sprinkling.') #agn_cache_file = os.path.join(twinklesDir, 'data', 'test_agn_galtile_cache.csv') self.agn_cache = pd.read_csv(agn_cache_file) #sne_cache_file = os.path.join(twinklesDir, 'data', 'test_sne_galtile_cache.csv') self.sne_cache = pd.read_csv(sne_cache_file) else: self.agn_cache = None self.sne_cache = None if defs_file is None: self.defs_file = os.path.join(twinklesDir, 'data', 'catsim_defs.csv') else: self.defs_file = defs_file specFileStart = 'Burst' for key, val in sorted(iteritems(SpecMap.subdir_map)): if re.match(key, specFileStart): galSpecDir = str(val) self.galDir = str( getPackageDir('sims_sed_library') + '/' + galSpecDir + '/') self.imSimBand = Bandpass() self.imSimBand.imsimBandpass() #self.LRG_name = 'Burst.25E09.1Z.spec' #self.LRG = Sed() #self.LRG.readSED_flambda(str(galDir + self.LRG_name)) #return #Calculate imsimband magnitudes of source galaxies for matching agn_fname = str( getPackageDir('sims_sed_library') + '/agnSED/agn.spec.gz') src_iband = self.lenscat['MAGI_IN'] src_z = self.lenscat['ZSRC'] self.src_mag_norm = [] for src, s_z in zip(src_iband, src_z): agn_sed = Sed() agn_sed.readSED_flambda(agn_fname) agn_sed.redshiftSED(s_z, dimming=True) self.src_mag_norm.append(matchBase().calcMagNorm( [src], agn_sed, self.bandpassDict)) #self.src_mag_norm = matchBase().calcMagNorm(src_iband, # [agn_sed]*len(src_iband), # # self.bandpassDict) self.defs_dict = {} with open(self.defs_file, 'r') as f: for line in f: line_defs = line.split(',') if len(line_defs) > 1: self.defs_dict[line_defs[0]] = line_defs[1].split('\n')[0]
import os from lsst.utils import getPackageDir from test_m_i import make_histogram from test_m_i import plot_color_mesh from agn_param_module import k_correction from lsst.sims.photUtils import CosmologyObject import numpy as np import json if __name__ == "__main__": sed_name = os.path.join(getPackageDir('sims_sed_library'), 'agnSED', 'agn.spec.gz') assert os.path.exists(sed_name) base_sed = Sed() base_sed.readSED_flambda(sed_name) bp_dict = BandpassDict.loadTotalBandpassesFromFiles() bp = bp_dict['i'] z_grid = np.arange(0.0, 16.0, 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, zz) k_grid[i_z] = k cosmo = CosmologyObject()
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
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 applyMLTflaring(self, valid_dexes, params, expmjd, parallax=None, ebv=None, quiescent_mags=None): """ parallax, ebv, and quiescent_mags are optional kwargs for use if you are calling this method outside the context of an InstanceCatalog (presumably with a numpy array of expmjd) parallax is the parallax of your objects in radians ebv is the E(B-V) value for your objects quiescent_mags is a dict keyed on ('u', 'g', 'r', 'i', 'z', 'y') with the quiescent magnitudes of the objects """ if parallax is None: parallax = self.column_by_name('parallax') if ebv is None: ebv = self.column_by_name('ebv') global _MLT_LC_NPZ global _MLT_LC_NPZ_NAME global _MLT_LC_TIME_CACHE global _MLT_LC_FLUX_CACHE # this needs to occur before loading the MLT light curve cache, # just in case the user wants to override the light curve cache # file by hand before generating the catalog if len(params) == 0: return numpy.array([[],[],[],[],[],[]]) if quiescent_mags is None: quiescent_mags = {} for mag_name in ('u', 'g', 'r', 'i', 'z', 'y'): if ('lsst_%s' % mag_name in self._actually_calculated_columns or 'delta_lsst_%s' % mag_name in self._actually_calculated_columns): quiescent_mags[mag_name] = self.column_by_name('quiescent_lsst_%s' % mag_name) if not hasattr(self, 'photParams'): raise RuntimeError("To apply MLT dwarf flaring, your " "InstanceCatalog must have a member variable " "photParams which is an instantiation of the " "class PhotometricParameters, which can be " "imported from lsst.sims.photUtils. " "This is so that your InstanceCatalog has " "knowledge of the effective area of the LSST " "mirror.") if _MLT_LC_NPZ is None or _MLT_LC_NPZ_NAME != self._mlt_lc_file or _MLT_LC_NPZ.fid is None: if not os.path.exists(self._mlt_lc_file): catutils_scripts = os.path.join(getPackageDir('sims_catUtils'), 'support_scripts') raise RuntimeError("The MLT flaring light curve file:\n" + "\n%s\n" % self._mlt_lc_file + "\ndoes not exist." +"\n\n" + "Go into %s " % catutils_scripts + "and run get_mdwarf_flares.sh " + "to get the data") _MLT_LC_NPZ = numpy.load(self._mlt_lc_file) sims_clean_up.targets.append(_MLT_LC_NPZ) _MLT_LC_NPZ_NAME = self._mlt_lc_file _MLT_LC_TIME_CACHE = {} _MLT_LC_FLUX_CACHE = {} if not hasattr(self, '_mlt_dust_lookup'): # Construct a look-up table to determine the factor # by which to multiply the flares' flux to account for # dust as a function of E(B-V). Recall that we are # modeling all MLT flares as 9000K blackbodies. if not hasattr(self, 'lsstBandpassDict'): raise RuntimeError('You are asking for MLT dwarf flaring ' 'magnitudes in a catalog that has not ' 'defined lsstBandpassDict. The MLT ' 'flaring magnitudes model does not know ' 'how to apply dust extinction to the ' 'flares without the member variable ' 'lsstBandpassDict being defined.') ebv_grid = numpy.arange(0.0, 7.01, 0.01) bb_wavelen = numpy.arange(200.0, 1500.0, 0.1) hc_over_k = 1.4387e7 # nm*K temp = 9000.0 # black body temperature in Kelvin exp_arg = hc_over_k/(temp*bb_wavelen) exp_term = 1.0/(numpy.exp(exp_arg) - 1.0) ln_exp_term = numpy.log(exp_term) # Blackbody f_lambda function; # discard normalizing factors; we only care about finding the # ratio of fluxes between the case with dust extinction and # the case without dust extinction log_bb_flambda = -5.0*numpy.log(bb_wavelen) + ln_exp_term bb_flambda = numpy.exp(log_bb_flambda) bb_sed = Sed(wavelen=bb_wavelen, flambda=bb_flambda) base_fluxes = self.lsstBandpassDict.fluxListForSed(bb_sed) a_x, b_x = bb_sed.setupCCMab() self._mlt_dust_lookup = {} self._mlt_dust_lookup['ebv'] = ebv_grid list_of_bp = self.lsstBandpassDict.keys() for bp in list_of_bp: self._mlt_dust_lookup[bp] = numpy.zeros(len(ebv_grid)) for iebv, ebv_val in enumerate(ebv_grid): wv, fl = bb_sed.addCCMDust(a_x, b_x, ebv=ebv_val, wavelen=bb_wavelen, flambda=bb_flambda) dusty_bb = Sed(wavelen=wv, flambda=fl) dusty_fluxes = self.lsstBandpassDict.fluxListForSed(dusty_bb) for ibp, bp in enumerate(list_of_bp): self._mlt_dust_lookup[bp][iebv] = dusty_fluxes[ibp]/base_fluxes[ibp] # get the distance to each star in parsecs _au_to_parsec = 1.0/206265.0 dd = _au_to_parsec/parallax # get the area of the sphere through which the star's energy # is radiating to get to us (in cm^2) _cm_per_parsec = 3.08576e16 sphere_area = 4.0*numpy.pi*numpy.power(dd*_cm_per_parsec, 2) flux_factor = self.photParams.effarea/sphere_area if isinstance(expmjd, numbers.Number): dMags = numpy.zeros((6, self.num_variable_obj(params))) else: dMags = numpy.zeros((6, self.num_variable_obj(params), len(expmjd))) mag_name_tuple = ('u', 'g', 'r', 'i', 'z', 'y') base_fluxes = {} base_mags = {} ss = Sed() for mag_name in mag_name_tuple: if ('lsst_%s' % mag_name in self._actually_calculated_columns or 'delta_lsst_%s' % mag_name in self._actually_calculated_columns): mm = quiescent_mags[mag_name] base_mags[mag_name] = mm base_fluxes[mag_name] = ss.fluxFromMag(mm) lc_name_arr = params['lc'].astype(str) lc_names_unique = numpy.unique(lc_name_arr) for lc_name in lc_names_unique: if 'None' in lc_name: continue use_this_lc = numpy.where(numpy.char.find(lc_name_arr, lc_name)==0) lc_name = lc_name.replace('.txt', '') # 2017 May 1 # There isn't supposed to be a 'late_inactive' light curve. # Unfortunately, I (Scott Daniel) assigned 'late_inactive' # light curves to some of the stars on our database. Rather # than fix the database table (which will take about a week of # compute time), I am going to fix the problem here by mapping # 'late_inactive' into 'late_active'. if 'late' in lc_name: lc_name = lc_name.replace('in', '') if lc_name in _MLT_LC_TIME_CACHE: raw_time_arr = _MLT_LC_TIME_CACHE[lc_name] else: raw_time_arr = _MLT_LC_NPZ['%s_time' % lc_name] _MLT_LC_TIME_CACHE[lc_name] = raw_time_arr time_arr = self._survey_start + raw_time_arr dt = time_arr.max() - time_arr.min() if isinstance(expmjd, numbers.Number): t_interp = (expmjd + params['t0'][use_this_lc]).astype(float) else: n_obj = len(use_this_lc[0]) n_time = len(expmjd) t_interp = numpy.ones(shape=(n_obj, n_time))*expmjd t_interp += numpy.array([[tt]*n_time for tt in params['t0'][use_this_lc].astype(float)]) while t_interp.max() > time_arr.max(): bad_dexes = numpy.where(t_interp>time_arr.max()) t_interp[bad_dexes] -= dt for i_mag, mag_name in enumerate(mag_name_tuple): if ('lsst_%s' % mag_name in self._actually_calculated_columns or 'delta_lsst_%s' % mag_name in self._actually_calculated_columns): flux_name = '%s_%s' % (lc_name, mag_name) if flux_name in _MLT_LC_FLUX_CACHE: flux_arr = _MLT_LC_FLUX_CACHE[flux_name] else: flux_arr = _MLT_LC_NPZ[flux_name] _MLT_LC_FLUX_CACHE[flux_name] = flux_arr dflux = numpy.interp(t_interp, time_arr, flux_arr) if isinstance(expmjd, numbers.Number): dflux *= flux_factor[use_this_lc] else: dflux *= numpy.array([flux_factor[use_this_lc]]*n_time).transpose() dust_factor = numpy.interp(ebv[use_this_lc], self._mlt_dust_lookup['ebv'], self._mlt_dust_lookup[mag_name]) if not isinstance(expmjd, numbers.Number): dust_factor = numpy.array([dust_factor]*n_time).transpose() dflux *= dust_factor if isinstance(expmjd, numbers.Number): local_base_fluxes = base_fluxes[mag_name][use_this_lc] local_base_mags = base_mags[mag_name][use_this_lc] else: local_base_fluxes = numpy.array([base_fluxes[mag_name][use_this_lc]]*n_time).transpose() local_base_mags = numpy.array([base_mags[mag_name][use_this_lc]]*n_time).transpose() dMags[i_mag][use_this_lc] = (ss.magFromFlux(local_base_fluxes + dflux) - local_base_mags) return dMags
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)
# Load LSST filters throughPath = os.getenv('LSST_THROUGHPUTS_BASELINE') keys = ['u', 'g', 'r', 'i', 'z', 'y'] nfilt = len(keys) filters = {} for filtername in keys: bp = np.loadtxt(os.path.join(throughPath, 'filter_' + filtername + '.dat'), dtype=zip(['wave', 'trans'], [float] * 2)) tempB = Bandpass() tempB.setBandpass(bp['wave'], bp['trans']) filters[filtername] = tempB filterWave = np.array([filters[f].calcEffWavelen()[0] for f in keys]) for i, spectrum in enumerate(moonSpectra['spectra']): tempSed = Sed() tempSed.setSED(moonWave, flambda=spectrum) for j, filtName in enumerate(keys): try: moonSpectra['mags'][i][j] = tempSed.calcMag(filters[filtName]) except: pass nbreak = 5 nrec = np.size(moonSpectra) for i in np.arange(nbreak): np.savez(os.path.join(outDir, 'moonSpectra_' + str(i) + '.npz'), wave=moonWave, spec=moonSpectra[i * nrec / nbreak:(i + 1) * nrec / nbreak], filterWave=filterWave)
def testSedBandpassMatch(self): """Test errors when bandpass and sed do not completely overlap in wavelength range.""" # Test case where they do match (no error message) sedwavelen = np.arange(self.wmin, self.wmax + .5, 1) sedflambda = np.ones(len(sedwavelen)) testsed = Sed(wavelen=sedwavelen, flambda=sedflambda) print('') # Test that no warning is made. with warnings.catch_warnings(record=True) as wa: w, f = testsed.resampleSED(wavelen_match=self.testbandpass.wavelen, wavelen=testsed.wavelen, flux=testsed.flambda) self.assertEqual(len(wa), 0) np.testing.assert_equal(w, testsed.wavelen) np.testing.assert_equal(f, testsed.flambda) # Test that warning is given for non-overlap at either top or bottom end of wavelength range. sedwavelen = np.arange(self.wmin, self.wmax - 50, 1) sedflambda = np.ones(len(sedwavelen)) testsed = Sed(wavelen=sedwavelen, flambda=sedflambda) with warnings.catch_warnings(record=True) as wa: testsed.resampleSED(wavelen_match=self.testbandpass.wavelen) self.assertEqual(len(wa), 1) self.assertIn('non-overlap', str(wa[-1].message)) np.testing.assert_equal(testsed.flambda[-1:], np.NaN) sedwavelen = np.arange(self.wmin + 50, self.wmax, 1) sedflambda = np.ones(len(sedwavelen)) testsed = Sed(wavelen=sedwavelen, flambda=sedflambda) with warnings.catch_warnings(record=True) as wa: testsed.resampleSED(wavelen_match=self.testbandpass.wavelen) self.assertEqual(len(wa), 1) self.assertIn('non-overlap', str(wa[-1].message)) np.testing.assert_equal(testsed.flambda[0], np.NaN) np.testing.assert_equal(testsed.flambda[49], np.NaN)
def test_alert_data_generation(self): dmag_cutoff = 0.005 mag_name_to_int = {'u': 0, 'g': 1, 'r': 2, 'i': 3, 'z' : 4, 'y': 5} _max_var_param_str = self.max_str_len class StarAlertTestDBObj(StellarAlertDBObjMixin, CatalogDBObject): objid = 'star_alert' tableid = 'stars' idColKey = 'simobjid' raColName = 'ra' decColName = 'dec' objectTypeId = 0 columns = [('raJ2000', 'ra*0.01745329252'), ('decJ2000', 'dec*0.01745329252'), ('parallax', 'px*0.01745329252/3600.0'), ('properMotionRa', 'pmra*0.01745329252/3600.0'), ('properMotionDec', 'pmdec*0.01745329252/3600.0'), ('radialVelocity', 'vrad'), ('variabilityParameters', 'varParamStr', str, _max_var_param_str)] class TestAlertsVarCatMixin(object): @register_method('alert_test') def applyAlertTest(self, valid_dexes, params, expmjd, variability_cache=None): if len(params) == 0: return np.array([[], [], [], [], [], []]) if isinstance(expmjd, numbers.Number): dmags_out = np.zeros((6, self.num_variable_obj(params))) else: dmags_out = np.zeros((6, self.num_variable_obj(params), len(expmjd))) for i_star in range(self.num_variable_obj(params)): if params['amp'][i_star] is not None: dmags = params['amp'][i_star]*np.cos(params['per'][i_star]*expmjd) for i_filter in range(6): dmags_out[i_filter][i_star] = dmags return dmags_out class TestAlertsVarCat(TestAlertsVarCatMixin, AlertStellarVariabilityCatalog): pass class TestAlertsTruthCat(TestAlertsVarCatMixin, CameraCoords, AstrometryStars, Variability, InstanceCatalog): column_outputs = ['uniqueId', 'chipName', 'dmagAlert', 'magAlert'] camera = obs_lsst_phosim.PhosimMapper().camera @compound('delta_umag', 'delta_gmag', 'delta_rmag', 'delta_imag', 'delta_zmag', 'delta_ymag') def get_TruthVariability(self): return self.applyVariability(self.column_by_name('varParamStr')) @cached def get_dmagAlert(self): return self.column_by_name('delta_%smag' % self.obs_metadata.bandpass) @cached def get_magAlert(self): return self.column_by_name('%smag' % self.obs_metadata.bandpass) + \ self.column_by_name('dmagAlert') star_db = StarAlertTestDBObj(database=self.star_db_name, driver='sqlite') # assemble the true light curves for each object; we need to figure out # if their np.max(dMag) ever goes over dmag_cutoff; then we will know if # we are supposed to simulate them true_lc_dict = {} true_lc_obshistid_dict = {} is_visible_dict = {} obs_dict = {} max_obshistid = -1 n_total_observations = 0 for obs in self.obs_list: obs_dict[obs.OpsimMetaData['obsHistID']] = obs obshistid = obs.OpsimMetaData['obsHistID'] if obshistid > max_obshistid: max_obshistid = obshistid cat = TestAlertsTruthCat(star_db, obs_metadata=obs) for line in cat.iter_catalog(): if line[1] is None: continue n_total_observations += 1 if line[0] not in true_lc_dict: true_lc_dict[line[0]] = {} true_lc_obshistid_dict[line[0]] = [] true_lc_dict[line[0]][obshistid] = line[2] true_lc_obshistid_dict[line[0]].append(obshistid) if line[0] not in is_visible_dict: is_visible_dict[line[0]] = False if line[3] <= self.obs_mag_cutoff[mag_name_to_int[obs.bandpass]]: is_visible_dict[line[0]] = True obshistid_bits = int(np.ceil(np.log(max_obshistid)/np.log(2))) skipped_due_to_mag = 0 objects_to_simulate = [] obshistid_unqid_set = set() for obj_id in true_lc_dict: dmag_max = -1.0 for obshistid in true_lc_dict[obj_id]: if np.abs(true_lc_dict[obj_id][obshistid]) > dmag_max: dmag_max = np.abs(true_lc_dict[obj_id][obshistid]) if dmag_max >= dmag_cutoff: if not is_visible_dict[obj_id]: skipped_due_to_mag += 1 continue objects_to_simulate.append(obj_id) for obshistid in true_lc_obshistid_dict[obj_id]: obshistid_unqid_set.add((obj_id << obshistid_bits) + obshistid) self.assertGreater(len(objects_to_simulate), 10) self.assertGreater(skipped_due_to_mag, 0) log_file_name = tempfile.mktemp(dir=self.output_dir, suffix='log.txt') alert_gen = AlertDataGenerator(testing=True) alert_gen.subdivide_obs(self.obs_list, htmid_level=6) for htmid in alert_gen.htmid_list: alert_gen.alert_data_from_htmid(htmid, star_db, photometry_class=TestAlertsVarCat, output_prefix='alert_test', output_dir=self.output_dir, dmag_cutoff=dmag_cutoff, log_file_name=log_file_name) dummy_sed = Sed() bp_dict = BandpassDict.loadTotalBandpassesFromFiles() phot_params = PhotometricParameters() # First, verify that the contents of the sqlite files are all correct n_tot_simulated = 0 alert_query = 'SELECT alert.uniqueId, alert.obshistId, meta.TAI, ' alert_query += 'meta.band, quiescent.flux, alert.dflux, ' alert_query += 'quiescent.snr, alert.snr, ' alert_query += 'alert.ra, alert.dec, alert.chipNum, ' alert_query += 'alert.xPix, alert.yPix, ast.pmRA, ast.pmDec, ' alert_query += 'ast.parallax ' alert_query += 'FROM alert_data AS alert ' alert_query += 'INNER JOIN metadata AS meta ON meta.obshistId=alert.obshistId ' alert_query += 'INNER JOIN quiescent_flux AS quiescent ' alert_query += 'ON quiescent.uniqueId=alert.uniqueId ' alert_query += 'AND quiescent.band=meta.band ' alert_query += 'INNER JOIN baseline_astrometry AS ast ' alert_query += 'ON ast.uniqueId=alert.uniqueId' alert_dtype = np.dtype([('uniqueId', int), ('obshistId', int), ('TAI', float), ('band', int), ('q_flux', float), ('dflux', float), ('q_snr', float), ('tot_snr', float), ('ra', float), ('dec', float), ('chipNum', int), ('xPix', float), ('yPix', float), ('pmRA', float), ('pmDec', float), ('parallax', float)]) sqlite_file_list = os.listdir(self.output_dir) n_tot_simulated = 0 obshistid_unqid_simulated_set = set() for file_name in sqlite_file_list: if not file_name.endswith('db'): continue full_name = os.path.join(self.output_dir, file_name) self.assertTrue(os.path.exists(full_name)) alert_db = DBObject(full_name, driver='sqlite') alert_data = alert_db.execute_arbitrary(alert_query, dtype=alert_dtype) if len(alert_data) == 0: continue mjd_list = ModifiedJulianDate.get_list(TAI=alert_data['TAI']) for i_obj in range(len(alert_data)): n_tot_simulated += 1 obshistid_unqid_simulated_set.add((alert_data['uniqueId'][i_obj] << obshistid_bits) + alert_data['obshistId'][i_obj]) unq = alert_data['uniqueId'][i_obj] obj_dex = (unq//1024)-1 self.assertAlmostEqual(self.pmra_truth[obj_dex], 0.001*alert_data['pmRA'][i_obj], 4) self.assertAlmostEqual(self.pmdec_truth[obj_dex], 0.001*alert_data['pmDec'][i_obj], 4) self.assertAlmostEqual(self.px_truth[obj_dex], 0.001*alert_data['parallax'][i_obj], 4) ra_truth, dec_truth = applyProperMotion(self.ra_truth[obj_dex], self.dec_truth[obj_dex], self.pmra_truth[obj_dex], self.pmdec_truth[obj_dex], self.px_truth[obj_dex], self.vrad_truth[obj_dex], mjd=mjd_list[i_obj]) distance = angularSeparation(ra_truth, dec_truth, alert_data['ra'][i_obj], alert_data['dec'][i_obj]) distance_arcsec = 3600.0*distance msg = '\ntruth: %e %e\nalert: %e %e\n' % (ra_truth, dec_truth, alert_data['ra'][i_obj], alert_data['dec'][i_obj]) self.assertLess(distance_arcsec, 0.0005, msg=msg) obs = obs_dict[alert_data['obshistId'][i_obj]] chipname = chipNameFromRaDec(self.ra_truth[obj_dex], self.dec_truth[obj_dex], pm_ra=self.pmra_truth[obj_dex], pm_dec=self.pmdec_truth[obj_dex], parallax=self.px_truth[obj_dex], v_rad=self.vrad_truth[obj_dex], obs_metadata=obs, camera=self.camera) chipnum = int(chipname.replace('R', '').replace('S', ''). replace(' ', '').replace(';', '').replace(',', ''). replace(':', '')) self.assertEqual(chipnum, alert_data['chipNum'][i_obj]) xpix, ypix = pixelCoordsFromRaDec(self.ra_truth[obj_dex], self.dec_truth[obj_dex], pm_ra=self.pmra_truth[obj_dex], pm_dec=self.pmdec_truth[obj_dex], parallax=self.px_truth[obj_dex], v_rad=self.vrad_truth[obj_dex], obs_metadata=obs, camera=self.camera) self.assertAlmostEqual(alert_data['xPix'][i_obj], xpix, 4) self.assertAlmostEqual(alert_data['yPix'][i_obj], ypix, 4) dmag_sim = -2.5*np.log10(1.0+alert_data['dflux'][i_obj]/alert_data['q_flux'][i_obj]) self.assertAlmostEqual(true_lc_dict[alert_data['uniqueId'][i_obj]][alert_data['obshistId'][i_obj]], dmag_sim, 3) mag_name = ('u', 'g', 'r', 'i', 'z', 'y')[alert_data['band'][i_obj]] m5 = obs.m5[mag_name] q_mag = dummy_sed.magFromFlux(alert_data['q_flux'][i_obj]) self.assertAlmostEqual(self.mag0_truth_dict[alert_data['band'][i_obj]][obj_dex], q_mag, 4) snr, gamma = calcSNR_m5(self.mag0_truth_dict[alert_data['band'][i_obj]][obj_dex], bp_dict[mag_name], self.obs_mag_cutoff[alert_data['band'][i_obj]], phot_params) self.assertAlmostEqual(snr/alert_data['q_snr'][i_obj], 1.0, 4) tot_mag = self.mag0_truth_dict[alert_data['band'][i_obj]][obj_dex] + \ true_lc_dict[alert_data['uniqueId'][i_obj]][alert_data['obshistId'][i_obj]] snr, gamma = calcSNR_m5(tot_mag, bp_dict[mag_name], m5, phot_params) self.assertAlmostEqual(snr/alert_data['tot_snr'][i_obj], 1.0, 4) for val in obshistid_unqid_set: self.assertIn(val, obshistid_unqid_simulated_set) self.assertEqual(len(obshistid_unqid_set), len(obshistid_unqid_simulated_set)) astrometry_query = 'SELECT uniqueId, ra, dec, TAI ' astrometry_query += 'FROM baseline_astrometry' astrometry_dtype = np.dtype([('uniqueId', int), ('ra', float), ('dec', float), ('TAI', float)]) tai_list = [] for obs in self.obs_list: tai_list.append(obs.mjd.TAI) tai_list = np.array(tai_list) n_tot_ast_simulated = 0 for file_name in sqlite_file_list: if not file_name.endswith('db'): continue full_name = os.path.join(self.output_dir, file_name) self.assertTrue(os.path.exists(full_name)) alert_db = DBObject(full_name, driver='sqlite') astrometry_data = alert_db.execute_arbitrary(astrometry_query, dtype=astrometry_dtype) if len(astrometry_data) == 0: continue mjd_list = ModifiedJulianDate.get_list(TAI=astrometry_data['TAI']) for i_obj in range(len(astrometry_data)): n_tot_ast_simulated += 1 obj_dex = (astrometry_data['uniqueId'][i_obj]//1024) - 1 ra_truth, dec_truth = applyProperMotion(self.ra_truth[obj_dex], self.dec_truth[obj_dex], self.pmra_truth[obj_dex], self.pmdec_truth[obj_dex], self.px_truth[obj_dex], self.vrad_truth[obj_dex], mjd=mjd_list[i_obj]) distance = angularSeparation(ra_truth, dec_truth, astrometry_data['ra'][i_obj], astrometry_data['dec'][i_obj]) self.assertLess(3600.0*distance, 0.0005) del alert_gen gc.collect() self.assertGreater(n_tot_simulated, 10) self.assertGreater(len(obshistid_unqid_simulated_set), 10) self.assertLess(len(obshistid_unqid_simulated_set), n_total_observations) self.assertGreater(n_tot_ast_simulated, 0)
class TwilightInterp(object): def __init__(self, mags=False, darkSkyMags=None, fitResults=None): """ Read the Solar spectrum into a handy object and compute mags in different filters mags: If true, only return the LSST filter magnitudes, otherwise return the full spectrum darkSkyMags = dict of the zenith dark sky values to be assumed. The twilight fits are done relative to the dark sky level. fitResults = dict of twilight parameters based on twilightFunc. Keys should be filter names. """ if darkSkyMags is None: darkSkyMags = { 'u': 22.8, 'g': 22.3, 'r': 21.2, 'i': 20.3, 'z': 19.3, 'y': 18.0, 'B': 22.35, 'G': 21.71, 'R': 21.3 } self.mags = mags dataDir = getPackageDir('sims_skybrightness_data') solarSaved = np.load(os.path.join(dataDir, 'solarSpec/solarSpec.npz')) self.solarSpec = Sed(wavelen=solarSaved['wave'], flambda=solarSaved['spec']) solarSaved.close() canonFilters = {} fnames = ['blue_canon.csv', 'green_canon.csv', 'red_canon.csv'] # Filter names, from bluest to reddest. self.filterNames = ['B', 'G', 'R'] for fname, filterName in zip(fnames, self.filterNames): bpdata = np.genfromtxt(os.path.join(dataDir, 'Canon/', fname), delimiter=', ', dtype=list( zip(['wave', 'through'], [float] * 2))) bpTemp = Bandpass() bpTemp.setBandpass(bpdata['wave'], bpdata['through']) canonFilters[filterName] = bpTemp # Tack on the LSST filters throughPath = os.path.join(getPackageDir('throughputs'), 'baseline') lsstKeys = ['u', 'g', 'r', 'i', 'z', 'y'] for key in lsstKeys: 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']) canonFilters[key] = tempB self.filterNames.append(key) # MAGIC NUMBERS from fitting the all-sky camera: # Code to generate values in sims_skybrightness/examples/fitTwiSlopesSimul.py # Which in turn uses twilight maps from sims_skybrightness/examples/buildTwilMaps.py # values are of the form: # 0: ratio of f^z_12 to f_dark^z # 1: slope of curve wrt sun alt # 2: airmass term (10^(arg[2]*(X-1))) # 3: azimuth term. # 4: zenith dark sky flux (erg/s/cm^2) # For z and y, just assuming the shape parameter fits are similar to the other bands. # Looks like the diode is not sensitive enough to detect faint sky. # Using the Patat et al 2006 I-band values for z and modeified a little for y as a temp fix. if fitResults is None: self.fitResults = { 'B': [ 7.56765633e+00, 2.29798055e+01, 2.86879956e-01, 3.01162143e-01, 2.58462036e-04 ], 'G': [ 2.38561156e+00, 2.29310648e+01, 2.97733083e-01, 3.16403197e-01, 7.29660095e-04 ], 'R': [ 1.75498017e+00, 2.22011802e+01, 2.98619033e-01, 3.28880254e-01, 3.24411056e-04 ], 'z': [2.29, 24.08, 0.3, 0.3, -666], 'y': [2.0, 24.08, 0.3, 0.3, -666] } # XXX-completely arbitrary fudge factor to make things brighter in the blue # Just copy the blue and say it's brighter. self.fitResults['u'] = [ 16., 2.29622121e+01, 2.85862729e-01, 2.99902574e-01, 2.32325117e-04 ] else: self.fitResults = fitResults # Take out any filters that don't have fit results self.filterNames = [ key for key in self.filterNames if key in self.fitResults ] self.effWave = [] self.solarMag = [] for filterName in self.filterNames: self.effWave.append(canonFilters[filterName].calcEffWavelen()[0]) self.solarMag.append( self.solarSpec.calcMag(canonFilters[filterName])) ord = np.argsort(self.effWave) self.filterNames = np.array(self.filterNames)[ord] self.effWave = np.array(self.effWave)[ord] self.solarMag = np.array(self.solarMag)[ord] # update the fit results to be zeropointed properly for key in self.fitResults: f0 = 10.**(-0.4 * (darkSkyMags[key] - np.log10(3631.))) self.fitResults[key][-1] = f0 self.solarWave = self.solarSpec.wavelen self.solarFlux = self.solarSpec.flambda # This one isn't as bad as the model grids, maybe we could get away with computing the magnitudes # in the __call__ each time. if mags: # Load up the LSST filters and convert the solarSpec.flabda and solarSpec.wavelen to fluxes throughPath = os.path.join(getPackageDir('throughputs'), 'baseline') self.lsstFilterNames = ['u', 'g', 'r', 'i', 'z', 'y'] self.lsstEquations = np.zeros( (np.size(self.lsstFilterNames), np.size(self.fitResults['B'])), dtype=float) self.lsstEffWave = [] fits = np.empty( (np.size(self.effWave), np.size(self.fitResults['B'])), dtype=float) for i, fn in enumerate(self.filterNames): fits[i, :] = self.fitResults[fn] for filtername in self.lsstFilterNames: bp = np.loadtxt(os.path.join(throughPath, 'filter_' + filtername + '.dat'), dtype=list(zip(['wave', 'trans'], [float] * 2))) tempB = Bandpass() tempB.setBandpass(bp['wave'], bp['trans']) self.lsstEffWave.append(tempB.calcEffWavelen()[0]) # Loop through the parameters and interpolate to new eff wavelengths for i in np.arange(self.lsstEquations[0, :].size): interp = InterpolatedUnivariateSpline(self.effWave, fits[:, i]) self.lsstEquations[:, i] = interp(self.lsstEffWave) # Set the dark sky flux for i, filterName in enumerate(self.lsstFilterNames): self.lsstEquations[i, -1] = 10.**( -0.4 * (darkSkyMags[filterName] - np.log10(3631.))) self.filterNameDict = {'u': 0, 'g': 1, 'r': 2, 'i': 3, 'z': 4, 'y': 5} def printFitsUsed(self): """ Print out the fit parameters being used """ print( '\\tablehead{\colhead{Filter} & \colhead{$r_{12/z}$} & \colhead{$a$ (1/radians)} & \colhead{$b$ (1/airmass)} & \colhead{$c$ (az term/airmass)} & \colhead{$f_z_dark$ (erg/s/cm$^2$)$\\times 10^8$} & \colhead{m$_z_dark$}}' ) for key in self.fitResults: numbers = '' for num in self.fitResults[key]: if num > .001: numbers += ' & %.2f' % num else: numbers += ' & %.2f' % (num * 1e8) print( key, numbers, ' & ', '%.2f' % (-2.5 * np.log10(self.fitResults[key][-1]) + np.log10(3631.))) def __call__(self, intepPoints, filterNames=['u', 'g', 'r', 'i', 'z', 'y']): if self.mags: return self.interpMag(intepPoints, filterNames=filterNames) else: return self.interpSpec(intepPoints) def interpMag(self, interpPoints, maxAM=2.5, limits=[np.radians(-5.), np.radians(-20.)], filterNames=['u', 'g', 'r', 'i', 'z', 'y']): """ Originally fit the twilight with a cutoff of sun altitude of -11 degrees. I think it can be safely extrapolated farther, but be warned you may be entering a regime where it breaks down. """ npts = len(filterNames) result = np.zeros((np.size(interpPoints), npts), dtype=float) good = np.where((interpPoints['sunAlt'] >= np.min(limits)) & (interpPoints['sunAlt'] <= np.max(limits)) & (interpPoints['airmass'] <= maxAM) & (interpPoints['airmass'] >= 1.))[0] for i, filterName in enumerate(filterNames): result[good, i] = twilightFunc( interpPoints[good], *self.lsstEquations[ self.filterNameDict[filterName], :].tolist()) return {'spec': result, 'wave': self.lsstEffWave} def interpSpec(self, interpPoints, maxAM=2.5, limits=[np.radians(-5.), np.radians(-20.)]): """ interpPoints should have airmass, azRelSun, and sunAlt. """ npts = np.size(self.solarWave) result = np.zeros((np.size(interpPoints), npts), dtype=float) good = np.where((interpPoints['sunAlt'] >= np.min(limits)) & (interpPoints['sunAlt'] <= np.max(limits)) & (interpPoints['airmass'] <= maxAM) & (interpPoints['airmass'] >= 1.))[0] # Compute the expected flux in each of the filters that we have fits for fluxes = [] for filterName in self.filterNames: fluxes.append( twilightFunc(interpPoints[good], *self.fitResults[filterName])) fluxes = np.array(fluxes) # ratio of model flux to raw solar flux: yvals = fluxes.T / (10.**(-0.4 * (self.solarMag - np.log10(3631.)))) # Find wavelengths bluer than cutoff blueRegion = np.where(self.solarWave < np.min(self.effWave)) for i, yval in enumerate(yvals): interpF = interp1d(self.effWave, yval, bounds_error=False, fill_value=yval[-1]) ratio = interpF(self.solarWave) interpBlue = InterpolatedUnivariateSpline(self.effWave, yval, k=1) ratio[blueRegion] = interpBlue(self.solarWave[blueRegion]) result[good[i]] = self.solarFlux * ratio return {'spec': result, 'wave': self.solarWave}
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 test_sne(grid_name, x1_vals, c0_vals, z_vals, abs_mag_vals, t_vals, dict_key, out_dict): bp_dict = BandpassDict.loadTotalBandpassesFromFiles() cosmo = CosmologyObject() n_samples = len(z_vals) mag_truth = np.zeros((6,n_samples), dtype=float) mag_interp = np.zeros((6,n_samples), dtype=float) mag_grid_dict = {} with h5py.File(grid_name, 'r') as in_file: param_mins = in_file['param_mins'].value d_params = in_file['d_params'].value t_grid = in_file['t_grid'].value for name in in_file.keys(): if name == 'param_mins': continue if name == 'd_params': continue if name == 't_grid': continue mag_grid_dict[name] = in_file[name].value t_start = time.time() for ii in range(n_samples): x1 = x1_vals[ii] c0 = c0_vals[ii] z = z_vals[ii] abs_mag = abs_mag_vals[ii] t = t_vals[ii] sn = sncosmo.Model(source='salt2-extended') sn.set(x1=x1,c=c0,z=z) sn.source.set_peakmag(abs_mag+cosmo.distanceModulus(z), band='bessellb', magsys='ab') flambda = 10.0*sn.flux(time=t, wave=10.0*bp_dict['g'].wavelen) ss = Sed(flambda=flambda, wavelen=bp_dict['g'].wavelen) mag_truth[:,ii] = bp_dict.magListForSed(ss) i_x1 = np.round((x1-param_mins[0])/d_params[0]).astype(int) i_c0 = np.round((c0-param_mins[1])/d_params[1]).astype(int) i_z = np.round((z-param_mins[2])/d_params[2]).astype(int) d_mag = abs_mag-param_mins[3] tag = i_x1+i_c0*100+i_z*10000 mag_grid = mag_grid_dict['%d' % tag] interp_mags = np.zeros(6, dtype=float) for i_bp in range(6): mm = np.interp(t, t_grid, mag_grid[i_bp])+d_mag mag_interp[i_bp,ii] = mm if ii>0 and ii%100 == 0: duration = (time.time()-t_start)/3600.0 pred = n_samples*duration/ii print('%d in %e hrs; predict %e' % (ii,duration,pred)) out_dict[dict_key] = (mag_interp, mag_truth)
dc2_data['accretion_rate']) dc2_abs_mag_i = M_i_from_L_Mass(dc2_log_edd_rat, np.log10(dc2_data['bhmass'])) dc2_cosmo = CosmologyObject(H0=71.0, Om0=0.265) DM = dc2_cosmo.distanceModulus(redshift=dc2_data['redshift']) 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, dc2_data['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 dc2_obs_mag_i = np.zeros(len(dc2_data), dtype=float) k_arr = np.interp(dc2_data['redshift'], z_grid, k_grid) print('calculating observed mag') for i_obj in range(len(dc2_data)): local_obs_mag = dc2_abs_mag_i[i_obj] + DM[i_obj] + k_arr[i_obj]
def testAddingToList(self): """ Test that we can add Seds to an already instantiated SedList """ imsimBand = Bandpass() imsimBand.imsimBandpass() nSed = 10 sedNameList_0 = self.getListOfSedNames(nSed) magNormList_0 = self.rng.random_sample(nSed)*5.0 + 15.0 internalAvList_0 = self.rng.random_sample(nSed)*0.3 + 0.1 redshiftList_0 = self.rng.random_sample(nSed)*5.0 galacticAvList_0 = self.rng.random_sample(nSed)*0.3 + 0.1 wavelen_match = np.arange(300.0, 1500.0, 10.0) testList = SedList(sedNameList_0, magNormList_0, fileDir=self.sedDir, internalAvList=internalAvList_0, redshiftList=redshiftList_0, galacticAvList=galacticAvList_0, wavelenMatch=wavelen_match) # experiment with adding different combinations of physical parameter lists # as None and not None for addIav in [True, False]: for addRedshift in [True, False]: for addGav in [True, False]: testList = SedList(sedNameList_0, magNormList_0, fileDir=self.sedDir, internalAvList=internalAvList_0, redshiftList=redshiftList_0, galacticAvList=galacticAvList_0, wavelenMatch=wavelen_match) sedNameList_1 = self.getListOfSedNames(nSed) magNormList_1 = self.rng.random_sample(nSed)*5.0 + 15.0 if addIav: internalAvList_1 = self.rng.random_sample(nSed)*0.3 + 0.1 else: internalAvList_1 = None if addRedshift: redshiftList_1 = self.rng.random_sample(nSed)*5.0 else: redshiftList_1 = None if addGav: galacticAvList_1 = self.rng.random_sample(nSed)*0.3 + 0.1 else: galacticAvList_1 = None testList.loadSedsFromList(sedNameList_1, magNormList_1, internalAvList=internalAvList_1, galacticAvList=galacticAvList_1, redshiftList=redshiftList_1) self.assertEqual(len(testList), 2*nSed) np.testing.assert_array_equal(wavelen_match, testList.wavelenMatch) for ix in range(len(sedNameList_0)): self.assertAlmostEqual(internalAvList_0[ix], testList.internalAvList[ix], 10) self.assertAlmostEqual(galacticAvList_0[ix], testList.galacticAvList[ix], 10) self.assertAlmostEqual(redshiftList_0[ix], testList.redshiftList[ix], 10) for ix in range(len(sedNameList_1)): if addIav: self.assertAlmostEqual(internalAvList_1[ix], testList.internalAvList[ix+nSed], 10) else: self.assertIsNone(testList.internalAvList[ix+nSed]) if addGav: self.assertAlmostEqual(galacticAvList_1[ix], testList.galacticAvList[ix+nSed], 10) else: self.assertIsNone(testList.galacticAvList[ix+nSed]) if addRedshift: self.assertAlmostEqual(redshiftList_1[ix], testList.redshiftList[ix+nSed], 10) else: self.assertIsNone(testList.redshiftList[ix+nSed]) for ix, (name, norm, iav, gav, zz) in \ enumerate(zip(sedNameList_0, magNormList_0, internalAvList_0, galacticAvList_0, redshiftList_0)): sedControl = Sed() sedControl.readSED_flambda(os.path.join(self.sedDir, name+'.gz')) fnorm = sedControl.calcFluxNorm(norm, imsimBand) sedControl.multiplyFluxNorm(fnorm) a_coeff, b_coeff = sedControl.setupCCM_ab() sedControl.addDust(a_coeff, b_coeff, A_v=iav) sedControl.redshiftSED(zz, dimming=True) sedControl.resampleSED(wavelen_match=wavelen_match) a_coeff, b_coeff = sedControl.setupCCM_ab() sedControl.addDust(a_coeff, b_coeff, A_v=gav) sedTest = testList[ix] np.testing.assert_array_equal(sedControl.wavelen, sedTest.wavelen) np.testing.assert_array_equal(sedControl.flambda, sedTest.flambda) np.testing.assert_array_equal(sedControl.fnu, sedTest.fnu) if not addIav: internalAvList_1 = [None] * nSed if not addRedshift: redshiftList_1 = [None] * nSed if not addGav: galacticAvList_1 = [None] * nSed for ix, (name, norm, iav, gav, zz) in \ enumerate(zip(sedNameList_1, magNormList_1, internalAvList_1, galacticAvList_1, redshiftList_1)): sedControl = Sed() sedControl.readSED_flambda(os.path.join(self.sedDir, name+'.gz')) fnorm = sedControl.calcFluxNorm(norm, imsimBand) sedControl.multiplyFluxNorm(fnorm) if addIav: a_coeff, b_coeff = sedControl.setupCCM_ab() sedControl.addDust(a_coeff, b_coeff, A_v=iav) if addRedshift: sedControl.redshiftSED(zz, dimming=True) sedControl.resampleSED(wavelen_match=wavelen_match) if addGav: a_coeff, b_coeff = sedControl.setupCCM_ab() sedControl.addDust(a_coeff, b_coeff, A_v=gav) sedTest = testList[ix+nSed] np.testing.assert_array_equal(sedControl.wavelen, sedTest.wavelen) np.testing.assert_array_equal(sedControl.flambda, sedTest.flambda) np.testing.assert_array_equal(sedControl.fnu, sedTest.fnu)
magnorm_interp = {} from lsst.sims.photUtils import PhotometricParameters, Bandpass phot_params = PhotometricParameters(nexp=1, exptime=30.0, gain=1) imsim = Bandpass() imsim.imsimBandpass() target=20000.0 for name in galaxy_sed_list: magnorm_interp[name] = {} magnorm_interp[name]['z'] = np.arange(0.0, 2.4, 0.2) magnorm_interp[name]['mag'] = np.zeros(len(magnorm_interp[name]['z']), dtype=float) for i_zz, zz in enumerate(magnorm_interp[name]['z']): ss = Sed() ss.readSED_flambda(os.path.join(galaxy_dir, name)) mag = ss.calcMag(imsim) ss.redshiftSED(zz, dimming=True) cts = ss.calcADU(bp_dict['r'], photParams=phot_params) magnorm = mag -2.5*np.log10(target/cts) ss = Sed() ss.readSED_flambda(os.path.join(galaxy_dir, name)) fnorm = ss.calcFluxNorm(magnorm, imsim) ss.multiplyFluxNorm(fnorm) ss.redshiftSED(zz, dimming=True) new_cts = ss.calcADU(bp_dict['r'], photParams=phot_params) d_ct = np.abs(new_cts-target) magnorm_interp[name]['mag'][i_zz] = magnorm
def testAlternateNormalizingBandpass(self): """ A reiteration of testAddingToList, but testing with a non-imsimBandpass normalizing bandpass """ normalizingBand = Bandpass() normalizingBand.readThroughput(os.path.join(getPackageDir('throughputs'), 'baseline', 'total_r.dat')) nSed = 10 sedNameList_0 = self.getListOfSedNames(nSed) magNormList_0 = self.rng.random_sample(nSed)*5.0 + 15.0 internalAvList_0 = self.rng.random_sample(nSed)*0.3 + 0.1 redshiftList_0 = self.rng.random_sample(nSed)*5.0 galacticAvList_0 = self.rng.random_sample(nSed)*0.3 + 0.1 wavelen_match = np.arange(300.0, 1500.0, 10.0) testList = SedList(sedNameList_0, magNormList_0, fileDir=self.sedDir, normalizingBandpass=normalizingBand, internalAvList=internalAvList_0, redshiftList=redshiftList_0, galacticAvList=galacticAvList_0, wavelenMatch=wavelen_match) sedNameList_1 = self.getListOfSedNames(nSed) magNormList_1 = self.rng.random_sample(nSed)*5.0 + 15.0 internalAvList_1 = self.rng.random_sample(nSed)*0.3 + 0.1 redshiftList_1 = self.rng.random_sample(nSed)*5.0 galacticAvList_1 = self.rng.random_sample(nSed)*0.3 + 0.1 testList.loadSedsFromList(sedNameList_1, magNormList_1, internalAvList=internalAvList_1, galacticAvList=galacticAvList_1, redshiftList=redshiftList_1) self.assertEqual(len(testList), 2*nSed) np.testing.assert_array_equal(wavelen_match, testList.wavelenMatch) for ix in range(len(sedNameList_0)): self.assertAlmostEqual(internalAvList_0[ix], testList.internalAvList[ix], 10) self.assertAlmostEqual(galacticAvList_0[ix], testList.galacticAvList[ix], 10) self.assertAlmostEqual(redshiftList_0[ix], testList.redshiftList[ix], 10) for ix in range(len(sedNameList_1)): self.assertAlmostEqual(internalAvList_1[ix], testList.internalAvList[ix+nSed], 10) self.assertAlmostEqual(galacticAvList_1[ix], testList.galacticAvList[ix+nSed], 10) self.assertAlmostEqual(redshiftList_1[ix], testList.redshiftList[ix+nSed], 10) for ix, (name, norm, iav, gav, zz) in \ enumerate(zip(sedNameList_0, magNormList_0, internalAvList_0, galacticAvList_0, redshiftList_0)): sedControl = Sed() sedControl.readSED_flambda(os.path.join(self.sedDir, name+'.gz')) fnorm = sedControl.calcFluxNorm(norm, normalizingBand) sedControl.multiplyFluxNorm(fnorm) a_coeff, b_coeff = sedControl.setupCCM_ab() sedControl.addDust(a_coeff, b_coeff, A_v=iav) sedControl.redshiftSED(zz, dimming=True) sedControl.resampleSED(wavelen_match=wavelen_match) a_coeff, b_coeff = sedControl.setupCCM_ab() sedControl.addDust(a_coeff, b_coeff, A_v=gav) sedTest = testList[ix] np.testing.assert_array_equal(sedControl.wavelen, sedTest.wavelen) np.testing.assert_array_equal(sedControl.flambda, sedTest.flambda) np.testing.assert_array_equal(sedControl.fnu, sedTest.fnu) for ix, (name, norm, iav, gav, zz) in \ enumerate(zip(sedNameList_1, magNormList_1, internalAvList_1, galacticAvList_1, redshiftList_1)): sedControl = Sed() sedControl.readSED_flambda(os.path.join(self.sedDir, name+'.gz')) fnorm = sedControl.calcFluxNorm(norm, normalizingBand) sedControl.multiplyFluxNorm(fnorm) a_coeff, b_coeff = sedControl.setupCCM_ab() sedControl.addDust(a_coeff, b_coeff, A_v=iav) sedControl.redshiftSED(zz, dimming=True) sedControl.resampleSED(wavelen_match=wavelen_match) a_coeff, b_coeff = sedControl.setupCCM_ab() sedControl.addDust(a_coeff, b_coeff, A_v=gav) sedTest = testList[ix+nSed] np.testing.assert_array_equal(sedControl.wavelen, sedTest.wavelen) np.testing.assert_array_equal(sedControl.flambda, sedTest.flambda) np.testing.assert_array_equal(sedControl.fnu, sedTest.fnu)
def testObjectPlacement(self): """ Test that GalSim places objects on the correct pixel by drawing images, reading them in, and then comparing the flux contained in circles of 2 fwhm radii about the object's expected positions with the actual expected flux of the objects. """ scratchDir = tempfile.mkdtemp(dir=ROOT, prefix='testObjectPlacement-') catName = os.path.join(scratchDir, 'placementCatalog.dat') imageRoot = os.path.join(scratchDir, 'placementImage') dbFileName = os.path.join(scratchDir, 'placementInputCatalog.dat') cameraDir = os.path.join(getPackageDir('sims_GalSimInterface'), 'tests', 'cameraData') camera = ReturnCamera(cameraDir) detector = camera[0] imageName = '%s_%s_u.fits' % (imageRoot, detector.getName()) controlSed = Sed() controlSed.readSED_flambda(os.path.join(getPackageDir('sims_sed_library'), 'flatSED', 'sed_flat.txt.gz')) uBandpass = Bandpass() uBandpass.readThroughput(os.path.join(getPackageDir('throughputs'), 'baseline', 'total_u.dat')) controlBandpass = Bandpass() controlBandpass.imsimBandpass() ff = controlSed.calcFluxNorm(self.magNorm, uBandpass) controlSed.multiplyFluxNorm(ff) a_int, b_int = controlSed.setupCCMab() controlSed.addCCMDust(a_int, b_int, A_v=0.1, R_v=3.1) nSamples = 3 rng = np.random.RandomState(42) pointingRaList = rng.random_sample(nSamples)*360.0 pointingDecList = rng.random_sample(nSamples)*180.0 - 90.0 rotSkyPosList = rng.random_sample(nSamples)*360.0 fwhmList = rng.random_sample(nSamples)*1.0 + 0.3 actualCounts = None for pointingRA, pointingDec, rotSkyPos, fwhm in \ zip(pointingRaList, pointingDecList, rotSkyPosList, fwhmList): obs = ObservationMetaData(pointingRA=pointingRA, pointingDec=pointingDec, boundType='circle', boundLength=4.0, mjd=49250.0, rotSkyPos=rotSkyPos) xDisplacementList = rng.random_sample(nSamples)*60.0-30.0 yDisplacementList = rng.random_sample(nSamples)*60.0-30.0 create_text_catalog(obs, dbFileName, xDisplacementList, yDisplacementList, mag_norm=[self.magNorm]*len(xDisplacementList)) db = placementFileDBObj(dbFileName, runtable='test') cat = placementCatalog(db, obs_metadata=obs) cat.camera_wrapper = GalSimCameraWrapper(camera) if actualCounts is None: actualCounts = controlSed.calcADU(uBandpass, cat.photParams) psf = SNRdocumentPSF(fwhm=fwhm) cat.setPSF(psf) cat.write_catalog(catName) cat.write_images(nameRoot=imageRoot) objRaList = [] objDecList = [] with open(catName, 'r') as inFile: for line in inFile: if line[0] != '#': words = line.split(';') objRaList.append(np.radians(np.float(words[2]))) objDecList.append(np.radians(np.float(words[3]))) objRaList = np.array(objRaList) objDecList = np.array(objDecList) self.assertGreater(len(objRaList), 0) # make sure we aren't testing # an empty catalog/image self.check_placement(imageName, objRaList, objDecList, [fwhm]*len(objRaList), np.array([actualCounts]*len(objRaList)), cat.photParams.gain, detector, camera, obs, epoch=2000.0) if os.path.exists(dbFileName): os.unlink(dbFileName) if os.path.exists(catName): os.unlink(catName) if os.path.exists(imageName): os.unlink(imageName) if os.path.exists(scratchDir): shutil.rmtree(scratchDir)
def testSetUp(self): """ Test the SedList can be successfully initialized """ ############## Try just reading in an normalizing some SEDs nSed = 10 sedNameList = self.getListOfSedNames(nSed) magNormList = self.rng.random_sample(nSed)*5.0 + 15.0 testList = SedList(sedNameList, magNormList, fileDir=self.sedDir) self.assertEqual(len(testList), nSed) self.assertIsNone(testList.internalAvList) self.assertIsNone(testList.galacticAvList) self.assertIsNone(testList.redshiftList) self.assertIsNone(testList.wavelenMatch) self.assertTrue(testList.cosmologicalDimming) imsimBand = Bandpass() imsimBand.imsimBandpass() for name, norm, sedTest in zip(sedNameList, magNormList, testList): sedControl = Sed() sedControl.readSED_flambda(os.path.join(self.sedDir, name+'.gz')) fnorm = sedControl.calcFluxNorm(norm, imsimBand) sedControl.multiplyFluxNorm(fnorm) np.testing.assert_array_equal(sedControl.wavelen, sedTest.wavelen) np.testing.assert_array_equal(sedControl.flambda, sedTest.flambda) np.testing.assert_array_equal(sedControl.fnu, sedTest.fnu) ################# now add an internalAv sedNameList = self.getListOfSedNames(nSed) magNormList = self.rng.random_sample(nSed)*5.0 + 15.0 internalAvList = self.rng.random_sample(nSed)*0.3 + 0.1 testList = SedList(sedNameList, magNormList, fileDir=self.sedDir, internalAvList=internalAvList) self.assertIsNone(testList.galacticAvList) self.assertIsNone(testList.redshiftList) self.assertIsNone(testList.wavelenMatch) self.assertTrue(testList.cosmologicalDimming) for avControl, avTest in zip(internalAvList, testList.internalAvList): self.assertAlmostEqual(avControl, avTest, 10) for name, norm, av, sedTest in zip(sedNameList, magNormList, internalAvList, testList): sedControl = Sed() sedControl.readSED_flambda(os.path.join(self.sedDir, name+'.gz')) fnorm = sedControl.calcFluxNorm(norm, imsimBand) sedControl.multiplyFluxNorm(fnorm) a_coeff, b_coeff = sedControl.setupCCM_ab() sedControl.addDust(a_coeff, b_coeff, A_v=av) np.testing.assert_array_equal(sedControl.wavelen, sedTest.wavelen) np.testing.assert_array_equal(sedControl.flambda, sedTest.flambda) np.testing.assert_array_equal(sedControl.fnu, sedTest.fnu) ################ now add redshift sedNameList = self.getListOfSedNames(nSed) magNormList = self.rng.random_sample(nSed)*5.0 + 15.0 internalAvList = self.rng.random_sample(nSed)*0.3 + 0.1 redshiftList = self.rng.random_sample(nSed)*5.0 testList = SedList(sedNameList, magNormList, fileDir=self.sedDir, internalAvList=internalAvList, redshiftList=redshiftList) self.assertIsNone(testList.galacticAvList) self.assertIsNone(testList.wavelenMatch) self.assertTrue(testList.cosmologicalDimming) for avControl, avTest in zip(internalAvList, testList.internalAvList): self.assertAlmostEqual(avControl, avTest, 10) for zControl, zTest in zip(redshiftList, testList.redshiftList): self.assertAlmostEqual(zControl, zTest, 10) for name, norm, av, zz, sedTest in \ zip(sedNameList, magNormList, internalAvList, redshiftList, testList): sedControl = Sed() sedControl.readSED_flambda(os.path.join(self.sedDir, name+'.gz')) fnorm = sedControl.calcFluxNorm(norm, imsimBand) sedControl.multiplyFluxNorm(fnorm) a_coeff, b_coeff = sedControl.setupCCM_ab() sedControl.addDust(a_coeff, b_coeff, A_v=av) sedControl.redshiftSED(zz, dimming=True) np.testing.assert_array_equal(sedControl.wavelen, sedTest.wavelen) np.testing.assert_array_equal(sedControl.flambda, sedTest.flambda) np.testing.assert_array_equal(sedControl.fnu, sedTest.fnu) ################# without cosmological dimming sedNameList = self.getListOfSedNames(nSed) magNormList = self.rng.random_sample(nSed)*5.0 + 15.0 internalAvList = self.rng.random_sample(nSed)*0.3 + 0.1 redshiftList = self.rng.random_sample(nSed)*5.0 testList = SedList(sedNameList, magNormList, fileDir=self.sedDir, internalAvList=internalAvList, redshiftList=redshiftList, cosmologicalDimming=False) self.assertIsNone(testList.galacticAvList) self.assertIsNone(testList.wavelenMatch) self.assertFalse(testList.cosmologicalDimming) for avControl, avTest in zip(internalAvList, testList.internalAvList): self.assertAlmostEqual(avControl, avTest, 10) for zControl, zTest in zip(redshiftList, testList.redshiftList): self.assertAlmostEqual(zControl, zTest, 10) for name, norm, av, zz, sedTest in \ zip(sedNameList, magNormList, internalAvList, redshiftList, testList): sedControl = Sed() sedControl.readSED_flambda(os.path.join(self.sedDir, name+'.gz')) fnorm = sedControl.calcFluxNorm(norm, imsimBand) sedControl.multiplyFluxNorm(fnorm) a_coeff, b_coeff = sedControl.setupCCM_ab() sedControl.addDust(a_coeff, b_coeff, A_v=av) sedControl.redshiftSED(zz, dimming=False) np.testing.assert_array_equal(sedControl.wavelen, sedTest.wavelen) np.testing.assert_array_equal(sedControl.flambda, sedTest.flambda) np.testing.assert_array_equal(sedControl.fnu, sedTest.fnu) ################ now add galacticAv sedNameList = self.getListOfSedNames(nSed) magNormList = self.rng.random_sample(nSed)*5.0 + 15.0 internalAvList = self.rng.random_sample(nSed)*0.3 + 0.1 redshiftList = self.rng.random_sample(nSed)*5.0 galacticAvList = self.rng.random_sample(nSed)*0.3 + 0.1 testList = SedList(sedNameList, magNormList, fileDir=self.sedDir, internalAvList=internalAvList, redshiftList=redshiftList, galacticAvList=galacticAvList) self.assertIsNone(testList.wavelenMatch) self.assertTrue(testList.cosmologicalDimming) for avControl, avTest in zip(internalAvList, testList.internalAvList): self.assertAlmostEqual(avControl, avTest, 10) for zControl, zTest in zip(redshiftList, testList.redshiftList): self.assertAlmostEqual(zControl, zTest, 10) for avControl, avTest in zip(galacticAvList, testList.galacticAvList): self.assertAlmostEqual(avControl, avTest, 10) for name, norm, av, zz, gav, sedTest in \ zip(sedNameList, magNormList, internalAvList, redshiftList, galacticAvList, testList): sedControl = Sed() sedControl.readSED_flambda(os.path.join(self.sedDir, name+'.gz')) fnorm = sedControl.calcFluxNorm(norm, imsimBand) sedControl.multiplyFluxNorm(fnorm) a_coeff, b_coeff = sedControl.setupCCM_ab() sedControl.addDust(a_coeff, b_coeff, A_v=av) sedControl.redshiftSED(zz, dimming=True) a_coeff, b_coeff = sedControl.setupCCM_ab() sedControl.addDust(a_coeff, b_coeff, A_v=gav) np.testing.assert_array_equal(sedControl.wavelen, sedTest.wavelen) np.testing.assert_array_equal(sedControl.flambda, sedTest.flambda) np.testing.assert_array_equal(sedControl.fnu, sedTest.fnu) ################ now use a wavelen_match sedNameList = self.getListOfSedNames(nSed) magNormList = self.rng.random_sample(nSed)*5.0 + 15.0 internalAvList = self.rng.random_sample(nSed)*0.3 + 0.1 redshiftList = self.rng.random_sample(nSed)*5.0 galacticAvList = self.rng.random_sample(nSed)*0.3 + 0.1 wavelen_match = np.arange(300.0, 1500.0, 10.0) testList = SedList(sedNameList, magNormList, fileDir=self.sedDir, internalAvList=internalAvList, redshiftList=redshiftList, galacticAvList=galacticAvList, wavelenMatch=wavelen_match) self.assertTrue(testList.cosmologicalDimming) for avControl, avTest in zip(internalAvList, testList.internalAvList): self.assertAlmostEqual(avControl, avTest, 10) for zControl, zTest in zip(redshiftList, testList.redshiftList): self.assertAlmostEqual(zControl, zTest, 10) for avControl, avTest in zip(galacticAvList, testList.galacticAvList): self.assertAlmostEqual(avControl, avTest, 10) np.testing.assert_array_equal(wavelen_match, testList.wavelenMatch) for name, norm, av, zz, gav, sedTest in \ zip(sedNameList, magNormList, internalAvList, redshiftList, galacticAvList, testList): sedControl = Sed() sedControl.readSED_flambda(os.path.join(self.sedDir, name+'.gz')) fnorm = sedControl.calcFluxNorm(norm, imsimBand) sedControl.multiplyFluxNorm(fnorm) a_coeff, b_coeff = sedControl.setupCCM_ab() sedControl.addDust(a_coeff, b_coeff, A_v=av) sedControl.redshiftSED(zz, dimming=True) sedControl.resampleSED(wavelen_match=wavelen_match) a_coeff, b_coeff = sedControl.setupCCM_ab() sedControl.addDust(a_coeff, b_coeff, A_v=gav) np.testing.assert_array_equal(sedControl.wavelen, sedTest.wavelen) np.testing.assert_array_equal(sedControl.flambda, sedTest.flambda) np.testing.assert_array_equal(sedControl.fnu, sedTest.fnu)
throughput_dtype = np.dtype([('wav_nm', float), ('throughput', float)]) sed_dtype = np.dtype([('wav_nm', float), ('flambda', float)]) phosim_ct_dtype = np.dtype([('id', int), ('phot', float), ('x', float), ('y', float)]) # read in and normalize the SED sed_name = os.path.join(phosim_dir, 'data', 'SEDs', 'flatSED', 'sed_flat_short.txt.gz') np_sed = np.genfromtxt(sed_name, dtype=sed_dtype) np_fnorm = get_sed_normalization(21.0, np_sed['wav_nm'], np_sed['flambda']) np_sed['flambda'] *= np_fnorm if _LSST_STACK_INSTALLED: phot_params = PhotometricParameters(nexp=1, exptime=30.0) spec = Sed() spec.readSED_flambda(sed_name) imsim_bp = Bandpass() imsim_bp.imsimBandpass() fnorm = spec.calcFluxNorm(21.0, imsim_bp) spec.multiplyFluxNorm(fnorm) # read in the throughputs for the mirrors, lenses, detector and atmosphere componentList = [m1_file, m2_file, m3_file, l1_file, l2_file, l3_file] if det_file.lower() != 'none': print('adding detector') componentList.append(det_file) if atmos_file.lower() != 'none': print('adding astmosphere') componentList.append(atmos_file)