def ZP_filtre(self, filtre): photParams = PhotometricParameters(bandpass=filtre) Diameter = 2. * np.sqrt( photParams.effarea * 1.e-4 / np.pi) # diameter in meter Cte = 3631. * np.pi * Diameter**2 * 2. * photParams.exptime / 4 / h / 1.e36 #print('hello Cte',Cte,Diameter,h,photParams.exptime) self.data['Skyb'][filtre] = Cte * np.power( Diameter / 6.5, 2.) * np.power( 2. * photParams.exptime / 30., 2.) * np.power( photParams.platescale, 2.) * np.power( 10., 0.4 * (25. - self.mag_sky[filtre])) * self.Sigmab[filtre] Zb = 181.8 * np.power(Diameter / 6.5, 2.) * self.Tb[filtre] mbZ = 25. + 2.5 * np.log10(Zb) filtre_trans = self.system[filtre] wavelen_min, wavelen_max, wavelen_step = filtre_trans.getWavelenLimits( None, None, None) bandpass = Bandpass(wavelen=filtre_trans.wavelen, sb=filtre_trans.sb) flatSed = Sed() flatSed.setFlatSED(wavelen_min, wavelen_max, wavelen_step) flux0 = np.power(10., -0.4 * mbZ) flatSed.multiplyFluxNorm(flux0) photParams = PhotometricParameters(bandpass=filtre) counts = flatSed.calcADU( bandpass, photParams=photParams) #number of counts for exptime self.data['zp'][filtre] = mbZ #print 'hello',counts/self.photParams.exptime self.data['counts_zp'][filtre] = counts / 2. * photParams.exptime
def testNoisyCatalog(self): """ Compare noisy and noiseless images drawn from the same catalog. Make sure that the pixel-by-pixel difference between the two is as expected from Poisson statistics. """ noisyCatName = os.path.join(self.scratch_dir, 'testNoisyCatalog.sav') cleanCatName = os.path.join(self.scratch_dir, 'testCleanCatalog.sav') gals = testGalaxyBulgeDBObj(driver=self.driver, database=self.dbName) noisyCat = noisyCatalog(gals, obs_metadata=self.obs_metadata) cleanCat = backgroundCatalog(gals, obs_metadata=self.obs_metadata) noisyCat.write_catalog(noisyCatName) cleanCat.write_catalog(cleanCatName) self.compareCatalogs(cleanCat, noisyCat, PhotometricParameters().gain, PhotometricParameters().readnoise) if os.path.exists(noisyCatName): os.unlink(noisyCatName) if os.path.exists(cleanCatName): os.unlink(cleanCatName)
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 testInit(self): """ Test that the init and getters of PhotometricParameters work properly """ defaults = PhotometricParameters() params = [ 'exptime', 'nexp', 'effarea', 'gain', 'readnoise', 'darkcurrent', 'othernoise', 'platescale', 'sigmaSys' ] for attribute in params: kwargs = {} kwargs[attribute] = -100.0 testCase = PhotometricParameters(**kwargs) for pp in params: if pp != attribute: self.assertEqual(defaults.__getattribute__(pp), testCase.__getattribute__(pp)) else: self.assertNotEqual(defaults.__getattribute__(pp), testCase.__getattribute__(pp)) self.assertEqual(testCase.__getattribute__(pp), -100.0)
def testSystematicUncertainty(self): """ Test that systematic uncertainty is added correctly. """ sigmaSys = 0.002 m5 = [23.5, 24.3, 22.1, 20.0, 19.5, 21.7] photParams = PhotometricParameters(sigmaSys=sigmaSys) bandpassDict = BandpassDict.loadTotalBandpassesFromFiles() obs_metadata = ObservationMetaData(unrefractedRA=23.0, unrefractedDec=45.0, m5=m5, bandpassName=self.bandpasses) magnitudes = bandpassDict.magListForSed(self.starSED) skySeds = [] for i in range(len(self.bandpasses)): skyDummy = Sed() skyDummy.readSED_flambda( os.path.join(lsst.utils.getPackageDir('throughputs'), 'baseline', 'darksky.dat')) normalizedSkyDummy = setM5(obs_metadata.m5[self.bandpasses[i]], skyDummy, self.totalBandpasses[i], self.hardwareBandpasses[i], seeing=LSSTdefaults().seeing( self.bandpasses[i]), photParams=PhotometricParameters()) skySeds.append(normalizedSkyDummy) for i in range(len(self.bandpasses)): snr = calcSNR_sed(self.starSED, self.totalBandpasses[i], skySeds[i], self.hardwareBandpasses[i], seeing=LSSTdefaults().seeing(self.bandpasses[i]), photParams=PhotometricParameters()) testSNR, gamma = calcSNR_m5( numpy.array([magnitudes[i]]), [self.totalBandpasses[i]], numpy.array([m5[i]]), photParams=PhotometricParameters(sigmaSys=0.0)) self.assertAlmostEqual(snr, testSNR[0], 10, msg = 'failed on calcSNR_m5 test %e != %e ' \ % (snr, testSNR[0])) control = numpy.sqrt( numpy.power(magErrorFromSNR(testSNR), 2) + numpy.power(sigmaSys, 2))
def ZP_filtre(self, filtre): """ ZP_filtre() : Compute zero point in filter band - platescale is 0.2 arcsec per pixel Tool function implemented by Phillie Gris (IN2P3) """ # extract parameters from lsst_sims photParams = PhotometricParameters(bandpass=filtre) # compute Diameter in meters : D=2*R = 2*sqrt(S/pi) Diameter = 2. * np.sqrt( photParams.effarea * 1.e-4 / np.pi) # diameter in meter # AB flux is 3.6307805477e-20 erg/cm2/s/Hz or 3.6307805477e-16 erg/m2/s/Hz # or 3.6307e-23 J/m2/s/Hz, h=6.626e-34 J.s # What is the meaning of this Cte ???? # especcialy what is 1e36 ? Cte = 3631. * np.pi * Diameter**2 * 2. * photParams.exptime / 4 / h / 1.e36 #print('Telescope::ZP_filtre: hello Cte=',Cte, ' Diam=',Diameter, 'h=',h,' exptime=',photParams.exptime) # What is the meaning of Skyb ????? self.data['Skyb'][filtre] = Cte * np.power( Diameter / 6.5, 2.) * np.power( 2. * photParams.exptime / 30., 2.) * np.power( photParams.platescale, 2.) * np.power( 10., 0.4 * (25. - self.mag_sky[filtre])) * self.Sigmab[filtre] #What is the meaning of Sigmab, Tb, Zb such Zb is used to calculate zero point Zb = 181.8 * np.power(Diameter / 6.5, 2.) * self.Tb[filtre] mbZ = 25. + 2.5 * np.log10(Zb) #filter without atmosphere filtre_trans = self.system[filtre] wavelen_min, wavelen_max, wavelen_step = filtre_trans.getWavelenLimits( None, None, None) bandpass = Bandpass(wavelen=filtre_trans.wavelen, sb=filtre_trans.sb) flatSed = Sed() flatSed.setFlatSED(wavelen_min, wavelen_max, wavelen_step) flux0 = np.power(10., -0.4 * mbZ) flatSed.multiplyFluxNorm(flux0) photParams = PhotometricParameters(bandpass=filtre) counts = flatSed.calcADU( bandpass, photParams=photParams) #number of counts for exptime self.data['zp'][filtre] = mbZ #print('Telescope::ZP_filtre hello',counts/self.photParams.exptime) self.data['counts_zp'][filtre] = counts / 2. * photParams.exptime
def 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 mag_to_flux_e_sec(self, mag, band, trans, sed): #this should be debugged at some point photrams = PhotometricParameters(bandpass=band) E_per_sec = sed.calcADU(bandpass=trans, photParams=photParams) e_per_sec /= exptime / photParams.gain return e_per_sec
def Calc_m5(self, filtre): filtre_trans = self.system[filtre] wavelen_min, wavelen_max, wavelen_step = filtre_trans.getWavelenLimits( None, None, None) bandpass = Bandpass(wavelen=filtre_trans.wavelen, sb=filtre_trans.sb) flatSedb = Sed() flatSedb.setFlatSED(wavelen_min, wavelen_max, wavelen_step) flux0b = np.power(10., -0.4 * self.mag_sky[filtre]) flatSedb.multiplyFluxNorm(flux0b) photParams = PhotometricParameters(bandpass=filtre) norm = photParams.platescale**2 / 2. * photParams.exptime / photParams.gain if self.atmos: self.data['m5'][filtre] = SignalToNoise.calcM5( flatSedb, self.atmosphere[filtre], self.system[filtre], photParams=photParams, FWHMeff=self.FWHMeff[filtre]) adu_int = flatSedb.calcADU(bandpass=self.atmosphere[filtre], photParams=photParams) self.data['flux_sky'][filtre] = adu_int * norm else: self.data['m5'][filtre] = SignalToNoise.calcM5( flatSedb, self.system[filtre], self.system[filtre], photParams=photParams, FWHMeff=self.FWHMeff[filtre]) adu_int = flatSedb.calcADU(bandpass=self.system[filtre], photParams=photParams) self.data['flux_sky'][filtre] = adu_int * norm
def __init__(self, observatory='LSST', hwBandpassDict=None, pointings=None, photparams=None, airmass_limit=4.0, mags=False, preciseAltAz=True): """ Parameters ---------- observatory : mags : preciseAltAz : hwBandpassDict : photparams : pointings : airmass_limit : """ self.sm = sb.SkyModel(observatory=observatory, mags=mags, preciseAltAz=preciseAltAz, airmass_limit=airmass_limit) self.adb = AirmassDependentBandpass(hwBandpassDict) self.photparams = photparams if self.photparams == 'LSST': self.photparams = PhotometricParameters()
def calcEffWavelen(hardware, title, throughputDir=None): photParams = PhotometricParameters() lsstDefaults = LSSTdefaults() atmos = {} stdAtmoFile = os.path.join(os.getenv('SYSENG_THROUGHPUTS_DIR'), 'siteProperties/pachonModtranAtm_12.dat') atmos['std'] = Bandpass() atmos['std'].readThroughput(stdAtmoFile) multiAtmos = False if throughputDir is None: throughputDir = os.getenv('THROUGHPUTS_DIR') if throughputDir is not None: multiAtmos = True Xarr = np.arange(1.0, 2.55, 0.1) for X in Xarr: atmos['%.1f' % X] = Bandpass() atmos['%.1f' % X].readThroughput( os.path.join(throughputDir, 'atmos/atmos_%d.dat' % (int(X * 10)))) atmoskeys = sorted(atmos.keys()) print title print ' %s' % (' '.join(atmoskeys)) system = Bandpass() effsb = {} for f in ['u', 'g', 'r', 'i', 'z', 'y']: writestring = '%s ' % f for k in atmoskeys: system.wavelen, system.sb = hardware[f].multiplyThroughputs( atmos[k].wavelen, atmos[k].sb) effphi, effsb[k] = system.calcEffWavelen() writestring += '%.2f ' % (effsb[k]) print writestring
def photometricParameters(phosim_commands): """ Factory function to create a PhotometricParameters object based on the instance catalog commands. Parameters ---------- dict The phosim commands provided by parsePhoSimInstanceFile. Returns ------- lsst.sims.photUtils.PhotometricParameters The object containing the photometric parameters. Notes ----- The gain is set to unity so that the resulting eimage has units of electrons/pixel. Read noise and dark current are set to zero. The effects from all three of those will be added by the electronics chain readout code. """ config = get_config() nsnap = phosim_commands['nsnap'] vistime = phosim_commands['vistime'] readout_time = config['electronics_readout']['readout_time'] exptime = (vistime - (nsnap-1)*readout_time)/float(nsnap) return PhotometricParameters(exptime=exptime, nexp=nsnap, gain=1, readnoise=0, darkcurrent=0, bandpass=phosim_commands['bandpass'])
def gamma(self, mag, band, exptime, nexp): """ gamma parameter estimation cf eq(5) of the paper LSST : from science drivers to reference design and anticipated data products with sigma_rand = 0.2 and m=m5 Parameters -------------- mag : float magnitudes band : str band exptime : float exposure time Returns ---------- gamma, mag_to_flux (float) """ if not hasattr(mag, '__iter__'): photParams = PhotometricParameters(nexp=nexp, exptime=exptime) counts, e_per_sec = self.mag_to_flux_e_sec(mag, band, exptime, nexp) gamma = 0.04 - 1. / (photParams.gain * counts) return gamma, e_per_sec else: r = [] for m, b, e, nexpo in zip(mag, band, exptime, nexp): gamma, flux_e = self.gamma(m, b, e, nexpo) r.append((gamma, flux_e)) return np.asarray(r)
def testNoSystematicUncertainty(self): """ Test that systematic uncertainty is handled correctly when set to None. """ m5 = [23.5, 24.3, 22.1, 20.0, 19.5, 21.7] photParams= PhotometricParameters(sigmaSys=0.0) obs_metadata = ObservationMetaData(unrefractedRA=23.0, unrefractedDec=45.0, m5=m5, bandpassName=self.filterNameList) magnitudes = [] for bp in self.bpList: mag = self.starSED.calcMag(bp) magnitudes.append(mag) skySedList = [] for bp, hardware, filterName in zip(self.bpList, self.hardwareList, self.filterNameList): skyDummy = Sed() skyDummy.readSED_flambda(os.path.join(lsst.utils.getPackageDir('throughputs'), 'baseline', 'darksky.dat')) normalizedSkyDummy = setM5(obs_metadata.m5[filterName], skyDummy, bp, hardware, seeing=LSSTdefaults().seeing(filterName), photParams=photParams) skySedList.append(normalizedSkyDummy) sigmaList = snr.calcMagError_m5(numpy.array(magnitudes), numpy.array(self.bpList), \ numpy.array(m5), photParams) for i in range(len(self.bpList)): snrat = snr.calcSNR_sed(self.starSED, self.bpList[i], skySedList[i], self.hardwareList[i], seeing=LSSTdefaults().seeing(self.filterNameList[i]), photParams=PhotometricParameters()) testSNR, gamma = snr.calcSNR_m5(numpy.array([magnitudes[i]]), [self.bpList[i]], numpy.array([m5[i]]), photParams=PhotometricParameters(sigmaSys=0.0)) self.assertAlmostEqual(snrat, testSNR[0], 10, msg = 'failed on calcSNR_m5 test %e != %e ' \ % (snrat, testSNR[0])) control = snr.magErrorFromSNR(testSNR) msg = '%e is not %e; failed' % (sigmaList[i], control) self.assertAlmostEqual(sigmaList[i], control, 10, msg=msg)
def test_stars(self): obs = ObservationMetaData(bandpassName=['c_u', 'c_g'], m5=[25.0, 26.0]) db_dtype = np.dtype([('id', np.int), ('raJ2000', np.float), ('decJ2000', np.float), ('sedFilename', str, 100), ('magNorm', np.float), ('galacticAv', np.float)]) inputDir = os.path.join(getPackageDir('sims_catUtils'), 'tests', 'testData') inputFile = os.path.join(inputDir, 'IndicesTestCatalogStars.txt') db = fileDBObject(inputFile, dtype=db_dtype, runtable='test', idColKey='id') cat = CartoonStars(db, obs_metadata=obs) with lsst.utils.tests.getTempFilePath('.txt') as catName: cat.write_catalog(catName) dtype = np.dtype([(name, np.float) for name in cat.column_outputs]) controlData = np.genfromtxt(catName, dtype=dtype, delimiter=',') db_columns = db.query_columns([ 'id', 'raJ2000', 'decJ2000', 'sedFilename', 'magNorm', 'galacticAv' ]) sedDir = os.path.join(getPackageDir('sims_sed_library'), 'starSED', 'kurucz') for ix, line in enumerate(next(db_columns)): spectrum = Sed() spectrum.readSED_flambda(os.path.join(sedDir, line[3])) fnorm = spectrum.calcFluxNorm(line[4], self.normband) spectrum.multiplyFluxNorm(fnorm) a_x, b_x = spectrum.setupCCM_ab() spectrum.addDust(a_x, b_x, A_v=line[5]) umag = spectrum.calcMag(self.uband) self.assertAlmostEqual(umag, controlData['cartoon_u'][ix], 3) gmag = spectrum.calcMag(self.gband) self.assertAlmostEqual(gmag, controlData['cartoon_g'][ix], 3) umagError, gamma = calcMagError_m5(umag, self.uband, obs.m5['c_u'], PhotometricParameters()) gmagError, gamma = calcMagError_m5(gmag, self.gband, obs.m5['c_g'], PhotometricParameters()) self.assertAlmostEqual(umagError, controlData['sigma_cartoon_u'][ix], 3) self.assertAlmostEqual(gmagError, controlData['sigma_cartoon_g'][ix], 3)
def make_galsim_detector(camera_wrapper, detname, phot_params, obs_metadata, epoch=2000.0): """ Create a GalSimDetector object given the desired detector name. Parameters ---------- camera_wrapper: lsst.sims.GalSimInterface.GalSimCameraWrapper An object representing the camera being simulated detname: str The name of the detector in the LSST focal plane to create, e.g., "R:2,2 S:1,1". phot_params: lsst.sims.photUtils.PhotometricParameters An object containing the physical parameters representing the photometric properties of the system obs_metadata: lsst.sims.utils.ObservationMetaData Characterizing the pointing of the telescope epoch: float Representing the Julian epoch against which RA, Dec are reckoned (default = 2000) Returns ------- GalSimDetector """ centerPupil = camera_wrapper.getCenterPupil(detname) centerPixel = camera_wrapper.getCenterPixel(detname) translationPupil = camera_wrapper.pupilCoordsFromPixelCoords(centerPixel.getX()+1, centerPixel.getY()+1, detname, obs_metadata) plateScale = np.sqrt(np.power(translationPupil[0]-centerPupil.getX(), 2) + np.power(translationPupil[1]-centerPupil.getY(), 2))/np.sqrt(2.0) plateScale = 3600.0*np.degrees(plateScale) # make a detector-custom photParams that copies all of the quantities # in the catalog photParams, except the platescale, which is # calculated above params = PhotometricParameters(exptime=phot_params.exptime, nexp=phot_params.nexp, effarea=phot_params.effarea, gain=phot_params.gain, readnoise=phot_params.readnoise, darkcurrent=phot_params.darkcurrent, othernoise=phot_params.othernoise, platescale=plateScale) return GalSimDetector(detname, camera_wrapper, obs_metadata=obs_metadata, epoch=epoch, photParams=params)
def testNoise(self): """ Test that ExampleCCDNoise puts the expected counts on an image by generating a flat image, adding noise and background to it, and calculating the variance of counts in the image. """ lsstDefaults = LSSTdefaults() gain = 2.5 readnoise = 6.0 photParams = PhotometricParameters(gain=gain, readnoise=readnoise) img = galsim.Image(100, 100) noise = ExampleCCDNoise(seed=42) m5 = 24.5 bandpass = Bandpass() bandpass.readThroughput( os.path.join(getPackageDir('throughputs'), 'baseline', 'total_r.dat')) background = calcSkyCountsPerPixelForM5( m5, bandpass, FWHMeff=lsstDefaults.FWHMeff('r'), photParams=photParams) noisyImage = noise.addNoiseAndBackground( img, bandpass, m5=m5, FWHMeff=lsstDefaults.FWHMeff('r'), photParams=photParams) mean = 0.0 var = 0.0 for ix in range(1, 101): for iy in range(1, 101): mean += noisyImage(ix, iy) mean = mean / 10000.0 for ix in range(1, 101): for iy in range(1, 101): var += (noisyImage(ix, iy) - mean) * (noisyImage(ix, iy) - mean) var = var / 9999.0 varElectrons = background * gain + readnoise varADU = varElectrons / (gain * gain) msg = 'background %e mean %e ' % (background, mean) self.assertLess(np.abs(background / mean - 1.0), 0.05, msg=msg) msg = 'var %e varADU %e ; ratio %e ; background %e' % ( var, varADU, var / varADU, background) self.assertLess(np.abs(var / varADU - 1.0), 0.05, msg=msg)
def testSignalToNoise(self): """ Test that calcSNR_m5 and calcSNR_sed give similar results """ defaults = LSSTdefaults() photParams = PhotometricParameters() totalDict, hardwareDict = BandpassDict.loadBandpassesFromFiles() skySED = Sed() skySED.readSED_flambda( os.path.join(lsst.utils.getPackageDir('throughputs'), 'baseline', 'darksky.dat')) m5 = [] for filt in totalDict: m5.append( calcM5(skySED, totalDict[filt], hardwareDict[filt], photParams, seeing=defaults.seeing(filt))) 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], totalDict.values()[2]) spectrum.multiplyFluxNorm(ff) magList = [] controlList = [] magList = [] for filt in totalDict: controlList.append( calcSNR_sed(spectrum, totalDict[filt], skySED, hardwareDict[filt], photParams, defaults.seeing(filt))) magList.append(spectrum.calcMag(totalDict[filt])) testList, gammaList = calcSNR_m5(numpy.array(magList), numpy.array(totalDict.values()), 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 __init__(self, **kwargs): self.filters = ['u', 'g', 'r', 'i', 'z', 'y'] self.Diameter = 6.5 #m self.DeltaT = 30 #s self.platescale = 0.2 #arsec self.gain = 2.3 self.pixel_size = 0.2 self.pixel_area = self.pixel_size**2 visittime = 30. self.expTime = dict( zip(self.filters, [30 for i in range(len(self.filters))])) self.photParams = PhotometricParameters(nexp=visittime / 15.) self.Cte = 3631. * np.pi * 6.6 * 6.5 * 30 / (100. * 4 * 6.626) #self.photParams = PhotometricParameters() params = [ 'mag_sky', 'm5', 'FWHMeff', 'Tb', 'Sigmab', 'zp', 'counts_zp', 'Skyb', 'flux_sky' ] self.data = {} for par in params: self.data[par] = {} self.data['FWHMeff'] = { 'u': 0.92, 'g': 0.87, 'r': 0.83, 'i': 0.80, 'z': 0.78, 'y': 0.76 } #self.data['mbsky']={'u': 22.92 ,'g': 22.27 ,'r':21.20,'i':20.47,'z':19.59,'y':18.63} self.atmos = True self.aerosol = True self.airmass = 1.2 if 'atmos' in kwargs.keys(): self.atmos = kwargs['atmos'] if 'aerosol' in kwargs.keys(): self.aerosol = kwargs['aerosol'] if 'airmass' in kwargs.keys(): self.airmass = kwargs['airmass'] self.throughputs = Throughputs(atmos=self.atmos, aerosol=self.aerosol) self.throughputs.Load_Atmosphere(self.airmass) self.Inputs() self.Sky() self.ZP()
def calcADUwrapper(sedName=None, magNorm=None, redshift=None, internalAv=None, internalRv=None, galacticAv=None, galacticRv=None, bandpass=None): """ Read in an SED and calculat the number of ADU produced by that SED in a specified bandpass Parameters ---------- sedName is a string specifying the file name of the SED magNorm is the normalizing magnitude of the SED in the imsimBandpass redshift is the redshift of the SED internalAv is the Av due to internal dust of the source (if a galaxy) internalRv is the Rv due to internal dust of the source (if a galaxy) galacticAv is the Av due to Milky Way dust between observer and source galacticRv is the Rv due to Milky Way dust between observer and source bandpass is an intantiation of Bandpass representing the band in which the ADUs are measured Returns ------- A float representing the number of ADUs measured in the bandpass """ imsimband = Bandpass() imsimband.imsimBandpass() sed = Sed() sed.readSED_flambda(sedName) fNorm = sed.calcFluxNorm(magNorm, imsimband) sed.multiplyFluxNorm(fNorm) if internalAv is not None and internalRv is not None: if internalAv != 0.0 and internalRv != 0.0: a_int, b_int = sed.setupCCM_ab() sed.addDust(a_int, b_int, A_v=internalAv, R_v=internalRv) if redshift is not None and redshift != 0.0: sed.redshiftSED(redshift, dimming=True) a_int, b_int = sed.setupCCM_ab() sed.addDust(a_int, b_int, A_v=galacticAv, R_v=galacticRv) adu = sed.calcADU(bandpass, photParams=PhotometricParameters()) return adu
def testExceptions(self): """ Test that exceptions get raised when they ought to by the PhotometricParameters constructor We will instantiate PhotometricParametrs with different incomplete lists of parameters set. We will verify that the returned error messages correctly point out which parameters were ignored. """ expectedMessage = { 'exptime': 'did not set exptime', 'nexp': 'did not set nexp', 'effarea': 'did not set effarea', 'gain': 'did not set gain', 'platescale': 'did not set platescale', 'sigmaSys': 'did not set sigmaSys', 'readnoise': 'did not set readnoise', 'darkcurrent': 'did not set darkcurrent', 'othernoise': 'did not set othernoise' } with self.assertRaises(RuntimeError) as context: PhotometricParameters(bandpass='******') for name in expectedMessage: self.assertTrue(expectedMessage[name] in context.exception.message) for name1 in expectedMessage: for name2 in expectedMessage: setParameters = {name1: 2.0, name2: 2.0} with self.assertRaises(RuntimeError) as context: PhotometricParameters(bandpass='******', **setParameters) for name3 in expectedMessage: if name3 not in setParameters: self.assertTrue(expectedMessage[name3] in context.exception.message) else: self.assertTrue(expectedMessage[name3] not in context.exception.message)
def test_raw_file_writing(self): """ Test the writing of raw files directly from a galsim.Image. This is mostly an operational test that the raw files can be written from a galsim image. """ camera_wrapper = sims_gsi.LSSTCameraWrapper() phot_params = PhotometricParameters() obs_md = ObservationMetaData(pointingRA=31.1133844, pointingDec=-10.0970060, rotSkyPos=69.0922930, mjd=59797.2854090, bandpassName='r') obs_md.OpsimMetaData = { 'obshistID': 161899, 'airmass': desc.imsim.airmass(43.6990272) } detname = "R:2,2 S:1,1" chipid = 'R{}_S{}'.format(detname[2:5:2], detname[8:11:2]) detector = sims_gsi.make_galsim_detector(camera_wrapper, detname, phot_params, obs_md) gs_interpreter = sims_gsi.GalSimInterpreter(detectors=[detector]) gs_image = gs_interpreter.blankImage(detector) raw_image = desc.imsim.ImageSource.create_from_galsim_image(gs_image) self.outfile = 'lsst_a_{}_r.fits'.format(chipid) # Add keyword values via an optional dict. added_keywords = {'GAUSFWHM': 0.4, 'FOOBAR': 'hello, world'} raw_image.write_fits_file(self.outfile, overwrite=True, added_keywords=added_keywords) # Test some keywords. with fits.open(self.outfile) as raw_file: hdr = raw_file[0].header self.assertAlmostEqual(hdr['RATEL'], obs_md.pointingRA) self.assertAlmostEqual(hdr['DECTEL'], obs_md.pointingDec) self.assertAlmostEqual(hdr['ROTANGLE'], obs_md.rotSkyPos) self.assertEqual(hdr['CHIPID'], chipid) # Ensure the following keywords are set. self.assertNotEqual(hdr['AMSTART'], hdr['AMEND']) self.assertNotEqual(hdr['HASTART'], hdr['HAEND']) self.assertEqual(hdr['DATE-OBS'], '2022-08-06T06:50:59.338') self.assertEqual(hdr['DATE-END'], '2022-08-06T06:51:29.338') self.assertEqual(hdr['TIMESYS'], 'TAI') self.assertEqual(hdr['OBSTYPE'], 'SKYEXP') # Test the added_keywords. for key, value in added_keywords.items(): self.assertEqual(hdr[key], value)
def setUpClass(cls): cls.scratchDir = tempfile.mkdtemp(dir=ROOT, prefix='allowedChipsTest-') cls.obs = ObservationMetaData(pointingRA=122.0, pointingDec=-29.1, mjd=57381.2, rotSkyPos=43.2, bandpassName='r') cls.camera = camTestUtils.CameraWrapper().camera cls.dbFileName = os.path.join(cls.scratchDir, 'allowed_chips_test_db.txt') if os.path.exists(cls.dbFileName): os.unlink(cls.dbFileName) cls.controlSed = Sed() cls.controlSed.readSED_flambda(os.path.join(getPackageDir('sims_sed_library'), 'flatSED', 'sed_flat.txt.gz')) cls.magNorm = 18.1 imsim = Bandpass() imsim.imsimBandpass() ff = cls.controlSed.calcFluxNorm(cls.magNorm, imsim) cls.controlSed.multiplyFluxNorm(ff) a_x, b_x = cls.controlSed.setupCCMab() cls.controlSed.addCCMDust(a_x, b_x, A_v=0.1, R_v=3.1) bpd = BandpassDict.loadTotalBandpassesFromFiles() pp = PhotometricParameters() cls.controlADU = cls.controlSed.calcADU(bpd['u'], pp) cls.countSigma = np.sqrt(cls.controlADU/pp.gain) cls.x_pix = 50 cls.y_pix = 50 x_list = [] y_list = [] name_list = [] for dd in cls.camera: x_list.append(cls.x_pix) y_list.append(cls.y_pix) name_list.append(dd.getName()) x_list = np.array(x_list) y_list = np.array(y_list) ra_list, dec_list = raDecFromPixelCoords(x_list, y_list, name_list, camera=cls.camera, obs_metadata=cls.obs, epoch=2000.0) dra_list = 3600.0*(ra_list-cls.obs.pointingRA) ddec_list = 3600.0*(dec_list-cls.obs.pointingDec) create_text_catalog(cls.obs, cls.dbFileName, dra_list, ddec_list, mag_norm=[cls.magNorm]*len(dra_list)) cls.db = allowedChipsFileDBObj(cls.dbFileName, runtable='test')
def CalcMyPhElMagnitudes(self): """ CalcMyElectronagnitudes(sed) - author : Sylvie Dagoret-Campagne - affiliation : LAL/IN2P3/CNRS/FRANCE - date : July 5th 2018 Calculate the instrumental magnitude (Photoelectrn unit) for all bands. """ all_magPhEl = [] for i, band in enumerate(self.filterlist): filter = self.lsst_atmos[band] #typical parameters of the band photParams = PhotometricParameters(bandpass=band) Diameter = 2. * np.sqrt( photParams.effarea * 1.e-4 / np.pi) # diameter in meter exptime = 2 * photParams.exptime # resample the wavelength each time for the filter wl, fnu = self.sed.getSED_fnu() wavelen, fnu = self.sed.resampleSED(wl, fnu, wavelen_match=filter.wavelen) fnu = np.nan_to_num( fnu ) # SDC(29/06/18) reset to 0 out of band where there are nan #this SED_nu is now in Jansky, units of 10-23 erg/cm2/s/Hz # 1 erg=10-7 J # 1 cm^-2 = 10^4 m^-2 # we have to multiply the SED_nu by 10-26 to be in J/m2/s/Hz self.sed = Sed(wavelen=wavelen, fnu=fnu, name=self.sed.name) # in Jansky divided by J (photon energy E=hc/lambda) Snu_Tl_dldivl = self.Calc_Integ_Sed(self.sed, filter) # in photoelectron per meter squared per meters per second # h is the Planck constant h=6.626x 10^-34 J.s dN_el = Snu_Tl_dldivl / h * 1e-26 * np.pi * Diameter**2 / 4. * exptime mag_el = -2.5 * np.log10(dN_el) print('CalcMyPhElMagnitudes :: band = {}, mag= {}'.format( i, mag_el)) all_magPhEl.append(mag_el) return np.array(all_magPhEl)
def CalcMyADUMagnitude_filter(self, band): """ CalcMyADUMagnitude_filter(band) - author : Sylvie Dagoret-Campagne - affiliation : LAL/IN2P3/CNRS/FRANCE - date : July 5th 2018 Calculate the instrumental magnitude (ADU unit) for one band. """ filter = self.lsst_atmos[band] #typical parameters of the band photParams = PhotometricParameters(bandpass=band) Diameter = 2. * np.sqrt( photParams.effarea * 1.e-4 / np.pi) # diameter in meter exptime = 2 * photParams.exptime gain = photParams.gain # resample the wavelength each time for the filter wl, fnu = self.sed.getSED_fnu() wavelen, fnu = self.sed.resampleSED(wl, fnu, wavelen_match=filter.wavelen) fnu = np.nan_to_num( fnu) # SDC(29/06/18) reset to 0 out of band where there are nan #this SED_nu is now in Jansky, units of 10-23 erg/cm2/s/Hz # 1 erg=10-7 J # 1 cm^-2 = 10^4 m^-2 # we have to multiply the SED_nu by 10-26 to be in J/m2/s/Hz self.sed = Sed(wavelen=wavelen, fnu=fnu, name=self.sed.name) # in Jansky divided by J (photon energy E=hc/lambda) Snu_Tl_dldivl = self.Calc_Integ_Sed(self.sed, filter) # in photoelectron per meter squared per meters per second # h is the Planck constant h=6.626x 10^-34 J.s dN_ADU = Snu_Tl_dldivl / h * 1e-26 * np.pi * Diameter**2 / 4. * exptime / gain mag_ADU = -2.5 * np.log10(dN_ADU) mag_ADU2 = -2.5 * np.log10( self.sed.calcADU(bandpass=filter, photParams=photParams, wavelen=wavelen, fnu=fnu)) #print('CalcMyADUMagnitude_filter :: band = {}, mag1(me)= {}, mag2(lsst_sim)={}, deltaM={}'.format(band,mag_ADU,mag_ADU2,mag_ADU-mag_ADU2)) return mag_ADU
def testSNRexceptions(self): """ test that calcSNR_m5 raises an exception when arguments are not of the right shape. """ photParams = PhotometricParameters() shortGamma = numpy.array([1.0, 1.0]) shortMagnitudes = numpy.array([22.0, 23.0]) magnitudes = 22.0*numpy.ones(6) self.assertRaises(RuntimeError, snr.calcSNR_m5, magnitudes, self.bpList, shortMagnitudes, photParams) self.assertRaises(RuntimeError, snr.calcSNR_m5, shortMagnitudes, self.bpList, magnitudes, photParams) self.assertRaises(RuntimeError, snr.calcSNR_m5, magnitudes, self.bpList, magnitudes, photParams, gamma=shortGamma) signalToNoise, gg = snr.calcSNR_m5(magnitudes, self.bpList, magnitudes, photParams)
def __init__(self, *args, **kwargs): self.lsstBandpassDict = BandpassDict.loadTotalBandpassesFromFiles() self._lightCurveCatalogClass = _sniaLightCurveCatalog self._filter_cat = None self._ax_cache = None self._bx_cache = None self._ax_bx_wavelen = None self.phot_params = PhotometricParameters() self.sn_universe = SNUniverse() self.sn_universe.suppressDimSN = False self.z_cutoff = 1.2 self._brightness_name = 'flux' super(SNIaLightCurveGenerator, self).__init__(*args, **kwargs)
def get_zp(self, what, band): """ decorator get zero points formula used here are extracted from LSE-40 Parameters --------------- what: str parameter to estimate band: str filter """ photParams = PhotometricParameters(bandpass=band) Diameter = 2. * np.sqrt( photParams.effarea * 1.e-4 / np.pi) # diameter in meter Cte = 3631. * np.pi * Diameter**2 * 2. * photParams.exptime / 4 / h / 1.e36 self.data['Skyb'][band] = Cte*np.power(Diameter/6.5, 2.)\ * np.power(2.*photParams.exptime/30., 2.)\ * np.power(photParams.platescale, 2.)\ * 10.**0.4*(25.-self.mag_sky(band))\ * self.Sigmab(band) Zb = 181.8 * np.power(Diameter / 6.5, 2.) * self.Tb(band) mbZ = 25. + 2.5 * np.log10(Zb) filtre_trans = self.system[band] wavelen_min, wavelen_max, wavelen_step = filtre_trans.getWavelenLimits( None, None, None) bandpass = Bandpass(wavelen=filtre_trans.wavelen, sb=filtre_trans.sb) flatSed = Sed() flatSed.setFlatSED(wavelen_min, wavelen_max, wavelen_step) flux0 = np.power(10., -0.4 * mbZ) flatSed.multiplyFluxNorm(flux0) photParams = PhotometricParameters(bandpass=band) # number of counts for exptime counts = flatSed.calcADU(bandpass, photParams=photParams) self.data['zp'][band] = mbZ self.data['counts_zp'][band] = counts / 2. * photParams.exptime
def Calc_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 testContainsRaDec(self): """ Test whether or not the method containsRaDec correctly identifies RA and Dec that fall inside and outside the detector """ photParams = PhotometricParameters() gsdet = GalSimDetector(self.camera[0].getName(), GalSimCameraWrapper(self.camera), self.obs, self.epoch, photParams=photParams) xxList = [gsdet.xMinPix, gsdet.xMaxPix] yyList = [gsdet.yMinPix, gsdet.yMaxPix] dxList = [-1.0, 1.0] dyList = [-1.0, 1.0] xPixList = [] yPixList = [] correctAnswer = [] for xx, yy, dx, dy in zip(xxList, yyList, dxList, dyList): xPixList.append(xx) yPixList.append(yy) correctAnswer.append(True) xPixList.append(xx + dx) yPixList.append(yy) correctAnswer.append(False) xPixList.append(xx) yPixList.append(yy + dy) correctAnswer.append(False) nameList = [gsdet.name] * len(xPixList) xPixList = np.array(xPixList) yPixList = np.array(yPixList) raList, decList = _raDecFromPixelCoords(xPixList, yPixList, nameList, camera=self.camera, obs_metadata=self.obs, epoch=self.epoch) testAnswer = gsdet.containsRaDec(raList, decList) for c, t in zip(correctAnswer, testAnswer): self.assertIs(c, t)
def testInit(self): """ Test that the init and getters of PhotometricParameters work properly """ defaults = PhotometricParameters() params = ['exptime', 'nexp', 'effarea', 'gain', 'readnoise', 'darkcurrent', 'othernoise', 'platescale', 'sigmaSys'] for attribute in params: kwargs = {} kwargs[attribute] = -100.0 testCase = PhotometricParameters(**kwargs) for pp in params: if pp != attribute: self.assertEqual(defaults.__getattribute__(pp), testCase.__getattribute__(pp)) else: self.assertNotEqual(defaults.__getattribute__(pp), testCase.__getattribute__(pp)) self.assertEqual(testCase.__getattribute__(pp), -100.0)
def testAssignment(self): """ Test that it is impossible to set PhotometricParameters on the fly """ testCase = PhotometricParameters() controlCase = PhotometricParameters() success = 0 msg = '' try: testCase.exptime = -1.0 success += 1 msg += 'was able to assign exptime; ' except: self.assertEqual(testCase.exptime, controlCase.exptime) try: testCase.nexp = -1.0 success += 1 msg += 'was able to assign nexp; ' except: self.assertEqual(testCase.nexp, controlCase.nexp) try: testCase.effarea = -1.0 success += 1 msg += 'was able to assign effarea; ' except: self.assertEqual(testCase.effarea, controlCase.effarea) try: testCase.gain = -1.0 success += 1 msg += 'was able to assign gain; ' except: self.assertEqual(testCase.gain, controlCase.gain) try: testCase.readnoise = -1.0 success += 1 msg += 'was able to assign readnoise; ' except: self.assertEqual(testCase.readnoise, controlCase.readnoise) try: testCase.darkcurrent = -1.0 success += 1 msg += 'was able to assign darkcurrent; ' except: self.assertEqual(testCase.darkcurrent, controlCase.darkcurrent) try: testCase.othernoise = -1.0 success += 1 msg += 'was able to assign othernoise; ' except: self.assertEqual(testCase.othernoise, controlCase.othernoise) try: testCase.platescale = -1.0 success += 1 msg += 'was able to assign platescale; ' except: self.assertEqual(testCase.platescale, controlCase.platescale) try: testCase.sigmaSys = -1.0 success += 1 msg += 'was able to assign sigmaSys; ' except: self.assertEqual(testCase.sigmaSys, controlCase.sigmaSys) try: testCase.bandpass = '******' success += 1 msg += 'was able to assign bandpass; ' except: self.assertEqual(testCase.bandpass, controlCase.bandpass) self.assertEqual(success, 0, msg=msg)