def lc(self, idx, maxObsHistID=None): """ Parameters ---------- """ if maxObsHistID is None: maxObsHistID = self.maxObsHistID # obtain the model parameters from the population paramDict = self.population.modelparams(idx) self.model.setModelParameters(**paramDict) myra = paramDict['ra'] mydec = paramDict['dec'] timeRange = (self.model.minMjd, self.model.maxMjd) if None not in timeRange: queryTime = 'expMJD < {1} and expMJD > {0}'.format(timeRange[0], timeRange[1]) df = self.pointings.copy().query(queryTime) else: df = self.pointings.copy() if self.pruneWithRadius: raise ValueError('Not implemented') numObs = len(self.pointings) modelFlux = np.zeros(numObs) fluxerr = np.zeros(numObs) sn = SNObject(myra, mydec) for i, rowtuple in enumerate(df.iterrows()): row = rowtuple[1] # print(row['expMJD'], row['filter'], row['fiveSigmaDepth']) bp = self.bandPasses[row['filter']] modelFlux[i] = self.model.modelFlux(row['expMJD'], bandpassobj=bp) fluxerr[i] = sn.catsimBandFluxError(time=row['expMJD'], bandpassobject=bp, fluxinMaggies=modelFlux[i], m5=row['fiveSigmaDepth']) rng = self.randomState df.reset_index(inplace=True) df['objid'] = np.ones(numObs)*np.int(idx) df['objid'] = df.objid.astype(np.int) df['fluxerr'] = fluxerr deviations = rng.normal(size=len(df)) df['deviations'] = deviations df['zp'] = 0. df['ModelFlux'] = modelFlux df['flux'] = df['ModelFlux'] + df['deviations'] * df['fluxerr'] df['zpsys']= 'ab' df['pid'] = self.pair_method(df.objid, df.obsHistID, self.maxObsHistID) df['pid'] = df.pid.astype(np.int) lc = df[['pid', 'obsHistID', 'objid', 'expMJD', 'filter', 'ModelFlux', 'fieldID', 'flux', 'fluxerr', 'deviations', 'zp', 'zpsys']] lc.set_index('pid', inplace=True) return lc
def get_snbrightness(self): """ getters for brightness related parameters of sn """ if self._sn_object_cache is None or len( self._sn_object_cache) > 1000000: self._sn_object_cache = {} c, x1, x0, t0, _z, ra, dec = self.column_by_name('c'),\ self.column_by_name('x1'),\ self.column_by_name('x0'),\ self.column_by_name('t0'),\ self.column_by_name('redshift'),\ self.column_by_name('raJ2000'),\ self.column_by_name('decJ2000') raDeg = np.degrees(ra) decDeg = np.degrees(dec) ebv = self.column_by_name('EBV') id_list = self.column_by_name('snid') bandname = self.obs_metadata.bandpass if isinstance(bandname, list): raise ValueError('bandname expected to be string, but is list\n') bandpass = self.lsstBandpassDict[bandname] # Initialize return array so that it contains the values you would get # if you passed through a t0=self.badvalues supernova vals = np.array([[0.0] * len(t0), [np.inf] * len(t0), [np.nan] * len(t0), [np.inf] * len(t0), [0.0] * len(t0)]).transpose() for i in np.where( np.logical_and( np.isfinite(t0), np.abs(self.mjdobs - t0) < self.maxTimeSNVisible))[0]: if id_list[i] in self._sn_object_cache: SNobject = self._sn_object_cache[id_list[i]] else: SNobject = SNObject() SNobject.set(z=_z[i], c=c[i], x1=x1[i], t0=t0[i], x0=x0[i]) SNobject.setCoords(ra=raDeg[i], dec=decDeg[i]) SNobject.set_MWebv(ebv[i]) self._sn_object_cache[id_list[i]] = SNobject if self.mjdobs <= SNobject.maxtime( ) and self.mjdobs >= SNobject.mintime(): # Calculate fluxes fluxinMaggies = SNobject.catsimBandFlux( time=self.mjdobs, bandpassobject=bandpass) mag = SNobject.catsimBandMag(time=self.mjdobs, fluxinMaggies=fluxinMaggies, bandpassobject=bandpass) vals[i, 0] = fluxinMaggies vals[i, 1] = mag flux_err = SNobject.catsimBandFluxError( time=self.mjdobs, bandpassobject=bandpass, m5=self.obs_metadata.m5[bandname], photParams=self.photometricparameters, fluxinMaggies=fluxinMaggies, magnitude=mag) mag_err = SNobject.catsimBandMagError( time=self.mjdobs, bandpassobject=bandpass, m5=self.obs_metadata.m5[bandname], photParams=self.photometricparameters, magnitude=mag) sed = SNobject.SNObjectSED(time=self.mjdobs, bandpass=self.lsstBandpassDict, applyExtinction=True) adu = sed.calcADU(bandpass, photParams=self.photometricparameters) vals[i, 2] = flux_err vals[i, 3] = mag_err vals[i, 4] = adu return (vals[:, 0], vals[:, 1], vals[:, 2], vals[:, 3], vals[:, 4])
class SNObject_tests(unittest.TestCase): @classmethod def tearDownClass(cls): sims_clean_up() def setUp(self): """ Setup tests SN_blank: A SNObject with no MW extinction """ mydir = get_config_dir() print('===============================') print('===============================') print (mydir) print('===============================') print('===============================') # A range of wavelengths in Ang self.wave = np.arange(3000., 12000., 50.) # Equivalent wavelenths in nm self.wavenm = self.wave / 10. # Time to be used as Peak self.mjdobs = 571190 # Check that we can set up a SED # with no extinction self.SN_blank = SNObject() self.SN_blank.setCoords(ra=30., dec=-60.) self.SN_blank.set(z=0.96, t0=571181, x1=2.66, c=0.353, x0=1.796e-6) self.SN_blank.set_MWebv(0.) self.SN_extincted = SNObject(ra=30., dec=-60.) self.SN_extincted.set(z=0.96, t0=571181, x1=2.66, c=0.353, x0=1.796112e-06) self.SNCosmoModel = self.SN_extincted.equivalentSNCosmoModel() self.rectify_photParams = PhotometricParameters() self.lsstBandPass = BandpassDict.loadTotalBandpassesFromFiles() self.SNCosmoBP = sncosmo.Bandpass(wave=self.lsstBandPass['r'].wavelen, trans=self.lsstBandPass['r'].sb, wave_unit=astropy.units.Unit('nm'), name='lsst_r') def tearDown(self): del self.SNCosmoBP del self.SN_blank del self.SN_extincted def test_SNstatenotEmpty(self): """ Check that the state of SNObject, stored in self.SNstate has valid entries for all keys and does not contain keys with None type Values. """ myDict = self.SN_extincted.SNstate for key in myDict: assert myDict[key] is not None def test_attributeDefaults(self): """ Check the defaults and the setter properties for rectifySED and modelOutSideRange """ snobj = SNObject(ra=30., dec=-60., source='salt2') self.assertEqual(snobj.rectifySED, True) self.assertEqual(snobj.modelOutSideTemporalRange, 'zero') snobj.rectifySED = False self.assertFalse(snobj.rectifySED, False) self.assertEqual(snobj.modelOutSideTemporalRange, 'zero') def test_raisingerror_forunimplementedmodelOutSideRange(self): """ check that correct error is raised if the user tries to assign an un-implemented model value to `sims.catUtils.supernovae.SNObject.modelOutSideTemporalRange` """ snobj = SNObject(ra=30., dec=-60., source='salt2') assert snobj.modelOutSideTemporalRange == 'zero' with self.assertRaises(ValueError) as context: snobj.modelOutSideTemporalRange = 'False' self.assertEqual('Model not implemented, defaulting to zero method\n', context.exception.args[0]) def test_rectifiedSED(self): """ Check for an extreme case that the SN seds are being rectified. This is done by setting up an extreme case where there will be negative seds, and checking that this is indeed the case, and checking that they are not negative if rectified. """ snobj = SNObject(ra=30., dec=-60., source='salt2') snobj.set(z=0.96, t0=self.mjdobs, x1=-3., x0=1.8e-6) snobj.rectifySED = False times = np.arange(self.mjdobs - 50., self.mjdobs + 150., 1.) badTimes = [] for time in times: sed = snobj.SNObjectSED(time=time, bandpass=self.lsstBandPass['r']) if any(sed.flambda < 0.): badTimes.append(time) # Check that there are negative SEDs assert(len(badTimes) > 0) snobj.rectifySED = True for time in badTimes: sed = snobj.SNObjectSED(time=time, bandpass=self.lsstBandPass['r']) self.assertGreaterEqual(sed.calcADU(bandpass=self.lsstBandPass['r'], photParams=self.rectify_photParams), 0.) self.assertFalse(any(sed.flambda < 0.)) def test_ComparebandFluxes2photUtils(self): """ The SNObject.catsimBandFlux computation uses the sims.photUtils.sed band flux computation under the hood. This test makes sure that these definitions are in sync """ snobject_r = self.SN_extincted.catsimBandFlux( bandpassobject=self.lsstBandPass['r'], time=self.mjdobs) # `sims.photUtils.Sed` sed = self.SN_extincted.SNObjectSED(time=self.mjdobs, bandpass=self.lsstBandPass['r']) sedflux = sed.calcFlux(bandpass=self.lsstBandPass['r']) np.testing.assert_allclose(snobject_r, sedflux / 3631.0) def test_CompareBandFluxes2SNCosmo(self): """ Compare the r band flux at a particular time computed in SNObject and SNCosmo for MW-extincted SEDs. While the underlying sed is obtained from SNCosmo the integration with the bandpass is an independent calculation in SNCosmo and catsim """ times = self.mjdobs catsim_r = self.SN_extincted.catsimBandFlux( bandpassobject=self.lsstBandPass['r'], time=times) sncosmo_r = self.SNCosmoModel.bandflux(band=self.SNCosmoBP, time=times, zpsys='ab', zp=0.) np.testing.assert_allclose(sncosmo_r, catsim_r) def test_CompareBandMags2SNCosmo(self): """ Compare the r band flux at a particular time computed in SNObject and SNCosmo for MW-extincted SEDs. Should work whenever the flux comparison above works. """ times = self.mjdobs catsim_r = self.SN_extincted.catsimBandMag( bandpassobject=self.lsstBandPass['r'], time=times) sncosmo_r = self.SNCosmoModel.bandmag(band=self.SNCosmoBP, time=times, magsys='ab') np.testing.assert_allclose(sncosmo_r, catsim_r) def test_CompareExtinctedSED2SNCosmo(self): """ Compare the extincted SEDS in SNCosmo and SNObject. Slightly more non-trivial than comparing unextincted SEDS, as the extinction in SNObject uses different code from SNCosmo. However, this is still using the same values of MWEBV, rather than reading it off a map. """ SNObjectSED = self.SN_extincted.SNObjectSED(time=self.mjdobs, wavelen=self.wavenm) SNCosmoSED = self.SNCosmoModel.flux(time=self.mjdobs, wave=self.wave) \ * 10. np.testing.assert_allclose(SNObjectSED.flambda, SNCosmoSED, rtol=1.0e-7) def test_CompareUnextinctedSED2SNCosmo(self): """ Compares the unextincted flux Densities in SNCosmo and SNObject. This is mereley a sanity check as SNObject uses SNCosmo under the hood. """ SNCosmoFluxDensity = self.SN_blank.flux(wave=self.wave, time=self.mjdobs) * 10. unextincted_sed = self.SN_blank.SNObjectSED(time=self.mjdobs, wavelen=self.wavenm) SNObjectFluxDensity = unextincted_sed.flambda np.testing.assert_allclose(SNCosmoFluxDensity, SNObjectFluxDensity, rtol=1.0e-7) def test_redshift(self): """ test that the redshift method works as expected by checking that if we redshift a SN from its original redshift orig_z to new_z where new_z is smaller (larger) than orig_z: - 1. x0 increases (decreases) - 2. source peak absolute magnitude in BesselB band stays the same """ from astropy.cosmology import FlatLambdaCDM cosmo = FlatLambdaCDM(H0=70., Om0=0.3) orig_z = self.SN_extincted.get('z') orig_x0 = self.SN_extincted.get('x0') peakabsMag = self.SN_extincted.source_peakabsmag('BessellB', 'AB', cosmo=cosmo) lowz = orig_z * 0.5 highz = orig_z * 2.0 # Test Case for lower redshift self.SN_extincted.redshift(z=lowz, cosmo=cosmo) low_x0 = self.SN_extincted.get('x0') lowPeakAbsMag = self.SN_extincted.source_peakabsmag('BessellB', 'AB', cosmo=cosmo) # Test 1. self.assertGreater(low_x0, orig_x0) # Test 2. self.assertAlmostEqual(peakabsMag, lowPeakAbsMag, places=14) # Test Case for higher redshift self.SN_extincted.redshift(z=highz, cosmo=cosmo) high_x0 = self.SN_extincted.get('x0') HiPeakAbsMag = self.SN_extincted.source_peakabsmag('BessellB', 'AB', cosmo=cosmo) # Test 1. self.assertLess(high_x0, orig_x0) # Test 2. self.assertAlmostEqual(peakabsMag, HiPeakAbsMag, places=14) def test_bandFluxErrorWorks(self): """ test that bandflux errors work even if the flux is negative """ times = self.mjdobs e = self.SN_extincted.catsimBandFluxError(times, self.lsstBandPass['r'], m5=24.5, fluxinMaggies=-1.0) assert isinstance(e, np.float) print(e) assert not(np.isinf(e) or np.isnan(e))
def main(ramax=58, ramin=56, decmin=-32, decmax=-31, t0=59215, tm=61406): query = query_tmpl.format(ramin, ramax, decmin, decmax) sntab = pd.read_sql_query(query, conn) #sntab.to_csv('./catalogs+tables/sn_cat_rectangle.csv') #if os.path.isfile('./catalogs+tables/full_t_visits_from_minion.csv'): # visitab = pd.read_csv('./catalogs+tables/full_t_visits_from_minion.csv') #else: res = ObsMetaData.getObservationMetaData(boundLength=2, boundType='circle', fieldRA=(ramin - 3, ramax + 3), fieldDec=(decmin - 3, decmax + 3), expMJD=(t0, tm)) parsed = [Odict(obsmd.summary['OpsimMetaData']) for obsmd in res] for obsmd, summ in zip(res, parsed): ditherRa = np.rad2deg(summ['descDitheredRA']) ditherDec = np.rad2deg(summ['descDitheredDec']) ditherRot = np.rad2deg(summ['descDitheredRotTelPos']) summ['descDitheredRotSkyPos'] = getRotSkyPos(ditherRa, ditherDec, obsmd, ditherRot) df = pd.DataFrame(parsed) df = df[df['filter'].isin(('g', 'r', 'i', 'z'))] X = df[[ 'obsHistID', 'filter', 'FWHMeff', 'descDitheredRA', 'descDitheredDec', 'descDitheredRotTelPos', 'airmass', 'fiveSigmaDepth', 'expMJD', 'descDitheredRotSkyPos', 'fieldRA', 'fieldDec', 'rotSkyPos', 'rotTelPos' ]].copy() X.descDitheredRA = np.rad2deg(X.descDitheredRA) X.descDitheredDec = np.rad2deg(X.descDitheredDec) X.descDitheredRotTelPos = np.rad2deg(X.descDitheredRotTelPos) #X.descDitheredRotSkyPos = np.rad2deg(X.descDitheredRotSkyPos) already in deg X.fieldRA = np.rad2deg(X.fieldRA) X.fieldDec = np.rad2deg(X.fieldDec) X.rotTelPos = np.rad2deg(X.rotTelPos) X.rotSkyPos = np.rad2deg(X.rotSkyPos) X['d1'] = angularSeparation(ramin, decmax, X.descDitheredRA.values, X.descDitheredDec.values) X['d2'] = angularSeparation(ramin, decmin, X.descDitheredRA.values, X.descDitheredDec.values) X['d3'] = angularSeparation(ramax, decmax, X.descDitheredRA.values, X.descDitheredDec.values) X['d4'] = angularSeparation(ramax, decmin, X.descDitheredRA.values, X.descDitheredDec.values) visitab = X.query('d1 < 1.75 | d2 < 1.75 | d3 < 1.75 |d4 < 1.75') del (X) del (df) visitab.to_csv('./catalogs+tables/full_t_visits_from_minion.csv') # setting the observation telescope status boresight = [] orientation = [] wcs_list = [] for avisit in visitab.itertuples(): bsight = geom.SpherePoint(avisit.descDitheredRA * geom.degrees, avisit.descDitheredDec * geom.degrees) orient = (90 - avisit.descDitheredRotSkyPos) * geom.degrees wcs_list.append([ makeSkyWcs(t, orient, flipX=False, boresight=bsight, projection='TAN') for t in trans ]) orientation.append(orient) boresight.append(bsight) times = visitab['expMJD'] bands = visitab['filter'] depths = visitab['fiveSigmaDepth'] #colnames = ['mjd', 'filter'] data_cols = {'mjd': times, 'filter': bands, 'visitn': visitab['obsHistID']} n_observ = [] n_trueobserv = [] for asn in sntab.itertuples(): sn_mod = SNObject(ra=asn.snra_in, dec=asn.sndec_in) sn_mod.set(z=asn.z_in, t0=asn.t0_in, x1=asn.x1_in, c=asn.c_in, x0=asn.x0_in) sn_skyp = afwGeom.SpherePoint(asn.snra_in, asn.sndec_in, afwGeom.degrees) size = len(times) sn_flxs = np.zeros(size) sn_mags = np.zeros(size) sn_flxe = np.zeros(size) sn_mage = np.zeros(size) sn_obsrvd = [] sn_observable = [] ii = 0 for mjd, filt, wcsl, m5 in zip(times, bands, wcs_list, depths): flux = sn_mod.catsimBandFlux(mjd, LSST_BPass[filt]) mag = sn_mod.catsimBandMag(LSST_BPass[filt], mjd, flux) flux_er = sn_mod.catsimBandFluxError(mjd, LSST_BPass[filt], m5, flux) mag_er = sn_mod.catsimBandMagError(mjd, LSST_BPass[filt], m5, magnitude=mag) # checking sensors containing this object contain = [box.contains(afwGeom.Point2I(wcs.skyToPixel(sn_skyp))) \ for box, wcs in zip(boxes, wcsl)] observed = np.sum(contain) > 0 observable = observed & (flux > 0.0 ) #(mag + mag_er < 27.0) & (mag_er < 0.5) # if observed: # print('Overlaps ccd', names[np.where(contain)[0][0]]) sn_observable.append(observable) sn_obsrvd.append(observed) sn_flxs[ii] = flux # done sn_mags[ii] = mag sn_flxe[ii] = flux_er sn_mage[ii] = mag_er ii += 1 data_cols[asn.snid_in + '_observable'] = sn_observable data_cols[asn.snid_in + '_observed'] = sn_obsrvd data_cols[asn.snid_in + '_flux'] = sn_flxs data_cols[asn.snid_in + '_fluxErr'] = sn_flxe data_cols[asn.snid_in + '_mag'] = sn_mags data_cols[asn.snid_in + '_magErr'] = sn_mage n_observ.append(np.sum(sn_obsrvd)) n_trueobserv.append(np.sum(sn_observable)) sntab['Nobserv'] = n_observ sntab['N_trueobserv'] = n_trueobserv lightcurves = pd.DataFrame(data_cols) dest_lc = './lightcurves/lightcurves_cat_rect_{}_{}_{}_{}.csv' lightcurves.to_csv(dest_lc.format(ramax, ramin, decmax, decmin)) dest_snfile = './catalogs+tables/supernovae_cat_rect_{}_{}_{}_{}.csv' sntab.to_csv(dest_snfile.format(ramax, ramin, decmax, decmin)) print("""Stored the lightcurves in {}, the SN catalog in {}""".format( dest_lc.format(ramax, ramin, decmax, decmin), dest_snfile.format(ramax, ramin, decmax, decmin))) return
def get_snbrightness(self): """ getters for brightness related parameters of sn """ if self._sn_object_cache is None or len(self._sn_object_cache) > 1000000: self._sn_object_cache = {} c, x1, x0, t0, _z, ra, dec = self.column_by_name('c'),\ self.column_by_name('x1'),\ self.column_by_name('x0'),\ self.column_by_name('t0'),\ self.column_by_name('redshift'),\ self.column_by_name('raJ2000'),\ self.column_by_name('decJ2000') raDeg = np.degrees(ra) decDeg = np.degrees(dec) ebv = self.column_by_name('EBV') id_list = self.column_by_name('snid') bandname = self.obs_metadata.bandpass if isinstance(bandname, list): raise ValueError('bandname expected to be string, but is list\n') bandpass = self.lsstBandpassDict[bandname] # Initialize return array so that it contains the values you would get # if you passed through a t0=self.badvalues supernova vals = np.array([[0.0]*len(t0), [np.inf]*len(t0), [np.nan]*len(t0), [np.inf]*len(t0), [0.0]*len(t0)]).transpose() for i in np.where(np.logical_and(np.isfinite(t0), np.abs(self.mjdobs - t0) < self.maxTimeSNVisible))[0]: if id_list[i] in self._sn_object_cache: SNobject = self._sn_object_cache[id_list[i]] else: SNobject = SNObject() SNobject.set(z=_z[i], c=c[i], x1=x1[i], t0=t0[i], x0=x0[i]) SNobject.setCoords(ra=raDeg[i], dec=decDeg[i]) SNobject.set_MWebv(ebv[i]) self._sn_object_cache[id_list[i]] = SNobject if self.mjdobs <= SNobject.maxtime() and self.mjdobs >= SNobject.mintime(): # Calculate fluxes fluxinMaggies = SNobject.catsimBandFlux(time=self.mjdobs, bandpassobject=bandpass) mag = SNobject.catsimBandMag(time=self.mjdobs, fluxinMaggies=fluxinMaggies, bandpassobject=bandpass) vals[i, 0] = fluxinMaggies vals[i, 1] = mag flux_err = SNobject.catsimBandFluxError(time=self.mjdobs, bandpassobject=bandpass, m5=self.obs_metadata.m5[ bandname], photParams=self.photometricparameters, fluxinMaggies=fluxinMaggies, magnitude=mag) mag_err = SNobject.catsimBandMagError(time=self.mjdobs, bandpassobject=bandpass, m5=self.obs_metadata.m5[ bandname], photParams=self.photometricparameters, magnitude=mag) sed = SNobject.SNObjectSED(time=self.mjdobs, bandpass=self.lsstBandpassDict, applyExtinction=True) adu = sed.calcADU(bandpass, photParams=self.photometricparameters) vals[i, 2] = flux_err vals[i, 3] = mag_err vals[i, 4] = adu return (vals[:, 0], vals[:, 1], vals[:, 2], vals[:, 3], vals[:, 4])