Пример #1
0
 def __init__(self, z=0, t0=0, x0=1, x1=0, c=0, snra=0, sndec=0):
     """
     Parameters
     ----------
     z: float [0]
          Redshift of the SNIa object to pass to sncosmo.
     t0: float [0]
          Time in mjd of phase=0, corresponding to the B-band
          maximum.
     x0: float [1]
          Normalization factor for the lightcurves.
     x1: float [0]
          Empirical parameter controlling the stretch in time of the
          light curves
     c: float [0]
          Empirical parameter controlling the colors.
     snra: float [0]
          RA in degrees of the SNIa.
     sndec: float [0]
          Dec in degrees of the SNIa.
     """
     self.sn_obj = SNObject(snra, sndec)
     self.sn_obj.set(z=z,
                     t0=t0,
                     x0=x0,
                     x1=x1,
                     c=c,
                     hostebv=0,
                     hostr_v=3.1,
                     mwebv=0,
                     mwr_v=3.1)
     self.bp_dict = self.lsst_bp_dict
Пример #2
0
    def astro_object(self, idValue, mjdOffset=59580.):
        """
        instance of the catsim representation of the astrophysical object.

        Parameters
        ----------
        idValue : int, mandatory
            index of the astro_object
        mjdOffset : float, optional, defaults to 59580.
            offset in time parameters in the database for the transient objects

        Returns
        -------
        Instance of astro_object with parameters from the database

        Examples
        --------
        >>> sn = reflc.astro_object(idValue=6001163623700)

        """
        df = self.get_params(idValue)
        sn = SNObject(ra=df.snra.values[0], dec=df.sndec.values[0])
        paramDict = dict()
        for param in ['t0', 'x0', 'x1', 'c']:
            paramDict[param] = df[param].values
        paramDict['t0'] += mjdOffset
        paramDict['z'] = df.redshift.values[0]
        sn.set(**paramDict)
        return sn
Пример #3
0
 def SNobj(fieldID, t0, snState=None, peakAbsMagBesselB=-19.3): 
     sn = SNObject(ra=np.degrees(so.ra(fieldID)), 
               dec=np.degrees(so.dec(fieldID)))
     sn.set(t0=t0)
     sn.set(z=0.5)
     sn.set_source_peakabsmag(peakAbsMagBesselB, 'bessellB', 'ab')
     return sn
Пример #4
0
    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
Пример #5
0
    def load_SNsed(self):
        """
        returns a list of SN seds in `lsst.sims.photUtils.Sed` observed within
        the spatio-temporal range specified by obs_metadata

        """
        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')

        SNobject = SNObject()

        raDeg = np.degrees(ra)
        decDeg = np.degrees(dec)

        sedlist = []
        for i in range(self.numobjs):
            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.mwEBVfromMaps()
            sed = SNobject.SNObjectSED(time=self.mjdobs,
                                       bandpass=self.lsstBandpassDict,
                                       applyExitinction=True)
            sedlist.append(sed)

        return sedlist
Пример #6
0
    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')
Пример #7
0
 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])
Пример #8
0
    def calc_sne_mags(self, obs_mjd, obs_filter):

        wavelen_max = 1800.
        wavelen_min = 30.
        wavelen_step = 0.1

        sn_magnorm_list = []
        sn_sed_names = []
        add_to_cat_list = []

        for idx in range(len(self.truth_cat)):

            sed_mjd = obs_mjd - self.truth_cat['t_delay'].iloc[idx]

            current_sn_obj = SNObject(ra=self.truth_cat['ra'].iloc[idx],
                                      dec=self.truth_cat['dec'].iloc[idx])
            current_sn_obj.set(z=self.truth_cat['redshift'].iloc[idx],
                               t0=self.truth_cat['t0'].iloc[idx],
                               x0=self.truth_cat['x0'].iloc[idx],
                               x1=self.truth_cat['x1'].iloc[idx],
                               c=self.truth_cat['c'].iloc[idx])

            # Following follows from
            # https://github.com/lsst/sims_catUtils/blob/master/python/lsst/sims/catUtils/mixins/sncat.py

            sn_sed_obj = current_sn_obj.SNObjectSourceSED(
                time=sed_mjd,
                wavelen=np.arange(wavelen_min, wavelen_max, wavelen_step))
            flux_500 = sn_sed_obj.flambda[np.where(
                sn_sed_obj.wavelen >= 499.99)][0]

            if flux_500 > 0.:
                sn_magnorm = sn_sed_obj.calcMag(bandpass=self.imSimBand)
                sn_name = None
                if self.write_sn_sed:
                    sn_name = '%s/specFileGLSN_%s_%s_%.4f.txt' % (
                        self.sed_folder_name,
                        self.truth_cat['dc2_sys_id'].iloc[idx],
                        self.truth_cat['image_number'].iloc[idx], obs_mjd)
                    sed_filename = '%s/%s' % (self.out_dir, sn_name)
                    sn_sed_obj.writeSED(sed_filename)
                    with open(sed_filename, 'rb') as f_in, gzip.open(
                            str(sed_filename + '.gz'), 'wb') as f_out:
                        shutil.copyfileobj(f_in, f_out)
                    os.remove(sed_filename)

                sn_magnorm_list.append(sn_magnorm)
                sn_sed_names.append(sn_name + '.gz')
                add_to_cat_list.append(idx)

        return add_to_cat_list, np.array(sn_magnorm_list), sn_sed_names
Пример #9
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.))
Пример #10
0
    def get_phosimVars(self):
        """
        Obtain variables sedFilepath to be used to obtain unique filenames
        for each SED for phoSim and MagNorm which is also used. Note that aside
        from acting as a getter, this also writes spectra to 
        `self.sn_sedfile_prefix`snid_mjd_band.dat for each observation of
        interest
        """
        # construct the unique filename
        # method: snid_mjd(to 4 places of decimal)_bandpassname
        mjd = "_{:0.4f}_".format(self.mjdobs)
        mjd += self.obs_metadata.bandpass + '.dat'
        fnames = np.array([
            self.sn_sedfile_prefix + str(int(elem)) + mjd if isinstance(
                elem, numbers.Number) else self.sn_sedfile_prefix + str(elem) +
            mjd for elem in self.column_by_name('snid')
        ],
                          dtype='str')

        c, x1, x0, t0, z = 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')

        bp = Bandpass()
        bp.imsimBandpass()

        magNorms = np.zeros(len(fnames))

        snobject = SNObject()
        snobject.rectifySED = True
        for i in range(len(self.column_by_name('snid'))):
            # if t0 is nan, this was set by the catalog for dim SN, or SN
            #   outside redshift range, We will not provide a SED file for these
            if np.isnan(t0[i]):
                magNorms[i] = np.nan
                fnames[i] = None

            else:
                snobject.set(c=c[i], x1=x1[i], x0=x0[i], t0=t0[i], z=z[i])
                if snobject.modelOutSideTemporalRange == 'zero':
                    if self.mjdobs > snobject.maxtime(
                    ) or self.mjdobs < snobject.mintime():
                        magNorms[i] = np.nan
                        fnames[i] = None

                # SED in rest frame
                sed = snobject.SNObjectSourceSED(time=self.mjdobs)
                try:
                    magNorms[i] = sed.calcMag(bandpass=bp)
                except:
                    # sed.flambda = 1.0e-20
                    magNorms[i] = 1000.  # sed.calcMag(bandpass=bp)

                if self.writeSedFile:
                    sed.writeSED(fnames[i])

        return (fnames, magNorms)
Пример #11
0
    def load_SNsed(self):
        """
        returns a list of SN seds in `lsst.sims.photUtils.Sed` observed within
        the spatio-temporal range specified by obs_metadata

        """
        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')

        SNobject = SNObject()

        raDeg = np.degrees(ra)
        decDeg = np.degrees(dec)

        sedlist = []
        for i in range(self.numobjs):
            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.mwEBVfromMaps()
            sed = SNobject.SNObjectSED(time=self.mjdobs,
                                       bandpass=self.lsstBandpassDict,
                                       applyExitinction=True)
            sedlist.append(sed)

        return sedlist
Пример #12
0
    def SN(self):
        """
        `lsst.sims.catsim.SNObject` instance with peakMJD set to t0
        """

        if self.snState is not None:
            return SNObject.fromSNState(self.snState)

        sn = SNObject(ra=self.radeg, dec=self.decdeg)
        sn.set(t0=self.t0)
        sn.set(z=0.5)
        sn.set_source_peakabsmag(self.bessellBpeakabsmag, 'bessellB', 'ab')

        return sn
Пример #13
0
 def SNobj(fieldID, t0, snState=None):
     sn = SNObject(ra=np.degrees(so.ra(fieldID)),
                   dec=np.degrees(so.dec(fieldID)))
     sn.set(t0=t0)
     sn.set(z=0.5)
     sn.set_source_peakabsmag(bessellBpeakabsmag, 'bessellB', 'ab')
     return sn
Пример #14
0
    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')
Пример #15
0
    def setUp(self):
        """
        Setup tests
        SN_blank: A SNObject with no MW extinction
        """

        from astropy.config import get_config_dir

        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.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')
Пример #16
0
    def SN(self):
        """
        `lsst.sims.catsim.SNObject` instance with peakMJD set to t0
        """

        if self.snState is not None:
            return SNObject.fromSNState(self.snState)

        sn = SNObject(ra=self.radeg, dec=self.decdeg)
        sn.set(t0=self.t0)
        sn.set(z=0.5)
        sn.set_source_peakabsmag(self.bessellBpeakabsmag, 'bessellB', 'ab')


        return sn
Пример #17
0
    def get_snfluxes(self):

        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)

        snobject = SNObject()
        # Initialize return array
        vals = np.zeros(shape=(self.numobjs, 19))
        for i, _ in enumerate(vals):
            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.mwEBVfromMaps()
            # Calculate fluxes
            vals[i, :6] = snobject.catsimManyBandFluxes(time=self.mjdobs,
                                                        bandpassDict=self.lsstBandpassDict,
                                                        observedBandPassInd=None)
            # Calculate magnitudes
            vals[i, 6:12] = snobject.catsimManyBandMags(time=self.mjdobs,
                                                        bandpassDict=self.lsstBandpassDict,
                                                        observedBandPassInd=None)

            vals[i, 12:18] = snobject.catsimManyBandADUs(time=self.mjdobs,
                                                         bandpassDict=self.lsstBandpassDict,
                                                         photParams=self.photometricparameters)
            vals[i, 18] = snobject.ebvofMW
        return (vals[:, 0], vals[:, 1], vals[:, 2], vals[:, 3],
                vals[:, 4], vals[:, 5], vals[:, 6], vals[:, 7],
                vals[:, 8], vals[:, 9], vals[:, 10], vals[:, 11],
                vals[:, 12], vals[:, 13], vals[:, 14], vals[:, 15],
                vals[:, 16], vals[:, 17], vals[:, 18])
Пример #18
0
    def SN(self):
        """
        `lsst.sims.catsim.SNObject` instance with peakMJD set to t0
        """

        if self._SN is not None:
            pass
            # return self._SN

        elif self.snState is not None:
            self._SN = SNObject.fromSNState(self.snState)
        else:
            sn = SNObject(ra=self.radeg, dec=self.decdeg)
            sn.set(t0=self.t0)
            sn.set(z=0.5)
            sn.set_source_peakabsmag(self.peakAbsMagBesselB, 'bessellB', 'ab')
            self._SN = sn

        return self._SN
Пример #19
0
    def get_phosimVars(self):
        """
        Obtain variables sedFilepath to be used to obtain unique filenames
        for each SED for phoSim and MagNorm which is also used. Note that aside
        from acting as a getter, this also writes spectra to 
        `self.sn_sedfile_prefix`snid_mjd_band.dat for each observation of
        interest
        """
        # construct the unique filename
        # method: snid_mjd(to 4 places of decimal)_bandpassname
        mjd = "_{:0.4f}_".format(self.mjdobs)
        mjd += self.obs_metadata.bandpass + '.dat'
        fnames = np.array([self.sn_sedfile_prefix + str(int(elem)) + mjd
                           if isinstance(elem, numbers.Number) else
                           self.sn_sedfile_prefix + str(elem) + mjd
                           for elem in self.column_by_name('snid')], dtype='str')

        c, x1, x0, t0, z = 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')

        bp = Bandpass()
        bp.imsimBandpass()

        magNorms = np.zeros(len(fnames))

        snobject = SNObject()
        snobject.rectifySED = True
        for i in range(len(self.column_by_name('snid'))):
            # if t0 is nan, this was set by the catalog for dim SN, or SN
            #   outside redshift range, We will not provide a SED file for these
            if np.isnan(t0[i]):
                magNorms[i] = np.nan
                fnames[i] = None

            else:
                snobject.set(c=c[i], x1=x1[i], x0=x0[i], t0=t0[i],
                             z=z[i])
                if snobject.modelOutSideTemporalRange == 'zero':
                    if self.mjdobs > snobject.maxtime() or self.mjdobs < snobject.mintime():
                        magNorms[i] = np.nan
                        fnames[i] = None

                # SED in rest frame
                sed = snobject.SNObjectSourceSED(time=self.mjdobs)
                try:
                    magNorms[i] = sed.calcMag(bandpass=bp)
                except:
                    # sed.flambda = 1.0e-20
                    magNorms[i] = 1000.  # sed.calcMag(bandpass=bp)

                if self.writeSedFile:
                    sed.writeSED(fnames[i])

        return (fnames, magNorms)
Пример #20
0
    def SN(self):
        """
        `lsst.sims.catsim.SNObject` instance with peakMJD set to t0
        """

        if self._SN is not None:
            pass
            # return self._SN

        elif self.snState is not None:
            self._SN = SNObject.fromSNState(self.snState)
        else :
            sn = SNObject(ra=self.radeg, dec=self.decdeg)
            sn.set(t0=self.t0)
            sn.set(z=0.5)
            sn.set_source_peakabsmag(self.peakAbsMagBesselB, 'bessellB', 'ab')
            self._SN = sn

        return self._SN
Пример #21
0
def getSNCosmomags(mjd, filt, snpars_table, snid_in='MS_9940_3541'):
    asn = snpars_table.loc[snpars_table['snid_in'] == snid_in]
    sn_mod = SNObject(ra=asn.snra_in[0], dec=asn.sndec_in[0])
    sn_mod.set(z=asn.z_in[0],
               t0=asn.t0_in[0],
               x1=asn.x1_in[0],
               c=asn.c_in[0],
               x0=asn.x0_in[0])

    # this is probably not the thing to do
    flux = sn_mod.catsimBandFlux(mjd, LSST_BPass[filt])
    mag = sn_mod.catsimBandMag(LSST_BPass[filt], mjd, flux)
    return (flux, mag)
Пример #22
0
    def _calculate_batch_of_sn(self, sn_truth_params, mjd_arr, filter_arr,
                               out_dict, tag):
        """
        For processing SNe in batches using multiprocessing

        -----
        sn_truth_params is a numpy array of json-ized
        dicts defining the state of an SNObject

        mjd_arr is a numpy array of the TAI times of
        observations

        filter_arr is a numpy array of ints indicating
        the filter being observed at each time

        out_dict is a multprocessing.Manager().dict() to store
        the results

        tag is an integer denoting which batch of SNe this is.
        """

        int_to_filter = 'ugrizy'

        mags = np.NaN*np.ones((len(sn_truth_params), len(mjd_arr)), dtype=float)

        for i_obj, sn_par in enumerate(sn_truth_params):
            sn_obj = SNObject.fromSNState(json.loads(sn_par))
            for i_time in range(len(mjd_arr)):
                mjd = mjd_arr[i_time]
                filter_name = int_to_filter[filter_arr[i_time]]
                if mjd < sn_obj.mintime() or mjd > sn_obj.maxtime():
                    continue
                bp = self._bp_dict[filter_name]
                sn_sed = sn_obj.SNObjectSED(mjd, bandpass=bp,
                                            applyExtinction=False)
                ff = sn_sed.calcFlux(bp)
                if ff>1.0e-300:
                    mm = sn_sed.magFromFlux(ff)
                    mags[i_obj][i_time] = mm

        out_dict[tag] = mags
Пример #23
0
    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])
Пример #24
0
    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]
Пример #25
0
class sprinkler():
    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]

    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 find_lens_candidates(self, galz, gal_mag):
        # search the OM10 catalog for all sources +- 0.1 dex in redshift
        # and within .25 mags of the CATSIM source
        w = np.where(
            (np.abs(np.log10(self.lenscat['ZSRC']) - np.log10(galz)) <= 0.1)
            & (np.abs(self.src_mag_norm - gal_mag) <= .25))[0]
        lens_candidates = self.lenscat[w]

        return lens_candidates

    def find_sne_lens_candidates(self, galz):

        w = np.where(
            (np.abs(np.log10(self.sne_catalog['zs']) - np.log10(galz)) <= 0.1))
        lens_candidates = self.sne_catalog.iloc[w]

        return lens_candidates

    def create_sn_sed(self, system_df, sn_ra, sn_dec, sed_mjd):

        sn_param_dict = copy.deepcopy(self.sn_obj.SNstate)
        sn_param_dict['_ra'] = sn_ra
        sn_param_dict['_dec'] = sn_dec
        sn_param_dict['z'] = system_df['zs']
        sn_param_dict['c'] = system_df['c']
        sn_param_dict['x0'] = system_df['x0']
        sn_param_dict['x1'] = system_df['x1']
        sn_param_dict['t0'] = system_df['t_start']
        # sn_param_dict['t0'] = 61681.083859  #+1500. ### For testing only

        current_sn_obj = self.sn_obj.fromSNState(sn_param_dict)
        current_sn_obj.mwEBVfromMaps()
        wavelen_max = 1800.
        wavelen_min = 30.
        wavelen_step = 0.1
        sn_sed_obj = current_sn_obj.SNObjectSED(time=sed_mjd,
                                                wavelen=np.arange(
                                                    wavelen_min, wavelen_max,
                                                    wavelen_step))
        flux_500 = sn_sed_obj.flambda[np.where(
            sn_sed_obj.wavelen >= 499.99)][0]

        if flux_500 > 0.:
            add_to_cat = True
            sn_magnorm = current_sn_obj.catsimBandMag(self.imSimBand, sed_mjd)
            sn_name = 'specFileGLSN_%i_%i_%.4f.txt' % (
                system_df['twinkles_sysno'], system_df['imno'], sed_mjd)
            sed_filename = '%s/%s' % (self.sed_path, sn_name)
            sn_sed_obj.writeSED(sed_filename)
            with open(sed_filename,
                      'rb') as f_in, gzip.open(str(sed_filename + '.gz'),
                                               'wb') as f_out:
                shutil.copyfileobj(f_in, f_out)
            os.remove(sed_filename)
        else:
            add_to_cat = False
            sn_magnorm = np.nan
            sn_name = None

        return add_to_cat, sn_magnorm, sn_name

    def update_catsim(self):
        # Remove the catsim object
        # Add lensed images to the catsim given source brightness and magnifications
        # Add lens galaxy to catsim
        return

    def catsim_to_phosim(self):
        # Pass this catsim to phosim to make images
        return
Пример #26
0
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
Пример #27
0
class SNObject_tests(unittest.TestCase):

    def setUp(self):
        """
        Setup tests
        SN_blank: A SNObject with no MW extinction
        """

        from astropy.config import get_config_dir

        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.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):
        pass

    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.keys():
            assert myDict[key] is not None
                
    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)
Пример #28
0
    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])
Пример #29
0
    def get_snfluxes(self):

        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)

        snobject = SNObject()
        # Initialize return array
        vals = np.zeros(shape=(self.numobjs, 19))
        for i, _ in enumerate(vals):
            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.mwEBVfromMaps()
            # Calculate fluxes
            vals[i, :6] = snobject.catsimManyBandFluxes(
                time=self.mjdobs,
                bandpassDict=self.lsstBandpassDict,
                observedBandPassInd=None)
            # Calculate magnitudes
            vals[i, 6:12] = snobject.catsimManyBandMags(
                time=self.mjdobs,
                bandpassDict=self.lsstBandpassDict,
                observedBandPassInd=None)

            vals[i, 12:18] = snobject.catsimManyBandADUs(
                time=self.mjdobs,
                bandpassDict=self.lsstBandpassDict,
                photParams=self.photometricparameters)
            vals[i, 18] = snobject.ebvofMW
        return (vals[:, 0], vals[:, 1], vals[:, 2], vals[:, 3], vals[:, 4],
                vals[:, 5], vals[:, 6], vals[:, 7], vals[:, 8], vals[:, 9],
                vals[:, 10], vals[:, 11], vals[:, 12], vals[:, 13],
                vals[:, 14], vals[:, 15], vals[:, 16], vals[:, 17], vals[:,
                                                                         18])
Пример #30
0
class SNSynthPhotFactory:
    """
    Factory class to return the SyntheticPhotometry objects for a SN Ia
    as a function of time.  This uses the 'salt2-extended' model in
    sncosmo as implemented in sims_catUtils.
    """
    lsst_bp_dict = BandpassDict.loadTotalBandpassesFromFiles()

    def __init__(self, z=0, t0=0, x0=1, x1=0, c=0, snra=0, sndec=0):
        """
        Parameters
        ----------
        z: float [0]
             Redshift of the SNIa object to pass to sncosmo.
        t0: float [0]
             Time in mjd of phase=0, corresponding to the B-band
             maximum.
        x0: float [1]
             Normalization factor for the lightcurves.
        x1: float [0]
             Empirical parameter controlling the stretch in time of the
             light curves
        c: float [0]
             Empirical parameter controlling the colors.
        snra: float [0]
             RA in degrees of the SNIa.
        sndec: float [0]
             Dec in degrees of the SNIa.
        """
        self.sn_obj = SNObject(snra, sndec)
        self.sn_obj.set(z=z,
                        t0=t0,
                        x0=x0,
                        x1=x1,
                        c=c,
                        hostebv=0,
                        hostr_v=3.1,
                        mwebv=0,
                        mwr_v=3.1)
        self.bp_dict = self.lsst_bp_dict

    def set_bp_dict(self, bp_dict):
        """
        Set the bandpass dictionary.

        Parameters
        ----------
        bp_dict: lsst.sims.photUtils.BandpassDict
             Dictionary containing the bandpasses. If None, the standard
             LSST total bandpasses will be used.
        """
        self.bp_dict = bp_dict

    def create(self, mjd):
        """
        Return a SyntheticPhotometry object for the specified time in MJD.

        Parameters
        ----------
        mjd: float
            Observation time in MJD.

        Returns
        -------
        desc.sims_truthcatalog.SyntheticPhotometry
        """
        # Create the Sed object.  Milky Way extinction will be
        # below, so set applyExtinction=False.
        sed = self.sn_obj.SNObjectSED(mjd,
                                      bandpass=self.bp_dict,
                                      applyExtinction=False)
        # The redshift was applied to the model SED computed by
        # sncosmo in the __init__ function, so set redshift=0 here.
        synth_phot = SyntheticPhotometry.create_from_sed(sed, redshift=0)
        synth_phot.add_MW_dust(*np.degrees(self.sn_obj.skycoord).flatten())
        return synth_phot

    def __getattr__(self, attr):
        # Pass any attribute access requests to the SNObject instance.
        return getattr(self.sn_obj, attr)
Пример #31
0
def validate_sne(cat_dir, obsid, fov_deg=2.1,
                 scatter_file=None, vanishing_file=None):
    """
    Parameters
    ----------
    cat_dir is the parent dir of $obsid

    obsid is the obsHistID of the pointing (an int)

    fov_deg is the radius of the field of view in degrees
    """

    project_dir = os.path.join('/global/projecta/projectdirs',
                               'lsst/groups/SSim/DC2/cosmoDC2_v1.1.4')

    sne_db_name = os.path.join(project_dir, 'sne_cosmoDC2_v1.1.4_MS_DDF.db')
    if not os.path.isfile(sne_db_name):
        raise RuntimeError("\n%s\nis not a file" % sne_db_name)

    instcat_dir = os.path.join(cat_dir, '%.8d' % obsid)
    if not os.path.isdir(instcat_dir):
        raise RuntimeError("\n%s\nis not a dir" % instcat_dir)

    sne_name = os.path.join(instcat_dir, 'sne_cat_%d.txt.gz' % obsid)
    if not os.path.isfile(sne_name):
        raise RuntimeError("\n%s\nis not a file" % sne_name)

    phosim_name = os.path.join(instcat_dir, 'phosim_cat_%d.txt' % obsid)
    if not os.path.isfile(phosim_name):
        raise RuntimeError("\n%s\nis not a file" % phosim_name)

    sed_dir = os.path.join(instcat_dir, "Dynamic")
    if not os.path.isdir(sed_dir):
        raise RuntimeError("\n%s\nis not a dir" % sed_dir)

    opsim_db = os.path.join("/global/projecta/projectdirs",
                            "lsst/groups/SSim/DC2",
                            "minion_1016_desc_dithered_v4_sfd.db")
    if not os.path.isfile(opsim_db):
        raise RuntimeError("\n%s\nis not a file" % opsim_db)

    band_from_int = 'ugrizy'
    bandpass = None
    with open(phosim_name, 'r') as in_file:
        for line in in_file:
            params = line.strip().split()
            if params[0] == 'filter':
                bandpass = band_from_int[int(params[1])]
                break
    if bandpass is None:
        raise RuntimeError("Failed to read in bandpass")

    bp_dict = photUtils.BandpassDict.loadTotalBandpassesFromFiles()

    with sqlite3.connect(opsim_db) as conn:
        c = conn.cursor()
        r = c.execute("SELECT descDitheredRA, descDitheredDec, expMJD FROM Summary "
                      "WHERE obsHistID==%d" % obsid).fetchall()
        pointing_ra = np.degrees(r[0][0])
        pointing_dec = np.degrees(r[0][1])
        expmjd = float(r[0][2])

    with sqlite3.connect(sne_db_name) as conn:
        c = conn.cursor()
        query = "SELECT snid_in, snra_in, sndec_in, "
        query += "c_in, mB, t0_in, x0_in, x1_in, z_in "
        query += "FROM sne_params WHERE ("

        where_clause = None
        half_space = htm.halfSpaceFromRaDec(pointing_ra, pointing_dec, fov_deg)
        bounds = half_space.findAllTrixels(6)

        for bound in bounds:
            if where_clause is not None:
                where_clause += " OR ("
            else:
                where_clause = "("

            if bound[0] == bound[1]:
                where_clause += "htmid_level_6==%d" % bound[0]
            else:
                where_clause += "htmid_level_6>=%d AND htmid_level_6<=%d" % (bound[0],bound[1])

            where_clause += ")"

        query += where_clause+")"

        sn_params = c.execute(query).fetchall()
    sn_ra = np.array([sn[1] for sn in sn_params])
    sn_dec = np.array([sn[2] for sn in sn_params])

    sn_d = angularSeparation(pointing_ra, pointing_dec,
                             sn_ra, sn_dec)

    valid = np.where(sn_d<=fov_deg)

    sn_ra_dec = {}
    sn_param_dict = {}
    for i_sn in valid[0]:
        sn = sn_params[i_sn]
        sn_param_dict[sn[0]] = sn[3:]
        sn_ra_dec[sn[0]] = sn[1:3]

    sne_in_instcat = set()
    d_mag_max = -1.0
    with gzip.open(sne_name, 'rb') as sne_cat_file:
        for sne_line in sne_cat_file:
            instcat_params = sne_line.strip().split(b' ')
            sne_id = instcat_params[1].decode('utf-8')
            if sne_id not in sn_param_dict:
                try:
                    sne_id_int = int(sne_id)
                    assert sne_id_int<1.5e10
                except (ValueError, AssertionError):
                    raise RuntimeError("\n%s\nnot in SNe db" % sne_id)

            sne_in_instcat.add(sne_id)

            control_params = sn_param_dict[sne_id]
            sed_name = os.path.join(instcat_dir, instcat_params[5].decode('utf-8'))
            if not os.path.isfile(sed_name):
                raise RuntimeError("\n%s\nis not a file" % sed_name)

            sed = photUtils.Sed()
            sed.readSED_flambda(sed_name, cache_sed=False)

            fnorm = photUtils.getImsimFluxNorm(sed, float(instcat_params[4]))
            sed.multiplyFluxNorm(fnorm)

            sed.redshiftSED(float(instcat_params[6]), dimming=True)
            a_x, b_x = sed.setupCCM_ab()
            A_v = float(instcat_params[15])
            R_v = float(instcat_params[16])
            EBV = A_v/R_v
            sed.addDust(a_x, b_x, A_v=A_v, R_v=R_v)

            sn_object = SNObject()
            sn_object.set_MWebv(EBV)
            sn_object.set(c=control_params[0], x1=control_params[4],
                          x0=control_params[3], t0=control_params[2],
                          z=control_params[5])

            sn_mag = sn_object.catsimBandMag(bp_dict[bandpass], expmjd)
            instcat_flux = sed.calcFlux(bp_dict[bandpass])
            instcat_mag = sed.magFromFlux(instcat_flux)
            d_mag = (sn_mag-instcat_mag)
            if not np.isfinite(d_mag):
                if np.isfinite(sn_mag) or np.isfinite(instcat_mag):
                    msg = '%s\ngave magnitudes %e %e (diff %e)' % (sne_id,
                                                                   sn_mag,
                                                                   instcat_mag,
                                                                   d_mag)
                    print(msg)

            if scatter_file is not None:
                scatter_file.write("%e %e %e\n" % (sn_mag, instcat_mag, d_mag))

            d_mag = np.abs(d_mag)
            if d_mag>d_mag_max:
                d_mag_max = d_mag
                #print('dmag %e -- %e (%e)' %
                #      (d_mag, instcat_mag,
                #       control_params[5]-float(instcat_params[6])))

    msg = '\n%s\n' % sne_name
    ct_missing = 0
    for sn_id in sn_param_dict:
        if sn_id in sne_in_instcat:
            continue
        control_params = sn_param_dict[sn_id]

        sn_object = SNObject()
        sn_object.set_MWebv(0.0)
        cc = control_params[0]
        x1 = control_params[4]
        x0 = control_params[3]
        t0 = control_params[2]
        zz = control_params[5]
        sn_object.set(c=cc, x1=x1, x0=x0, t0=t0, z=zz)

        sn_mag = sn_object.catsimBandMag(bp_dict[bandpass], expmjd)
        if vanishing_file is not None and np.isfinite(sn_mag):
            vanishing_file.write('%d %s %s %e ' % (obsid, bandpass, sn_id, sn_mag))
            vanishing_file.write('%e %e %e %.4f %e %.4f %e\n' %
                                 (cc,x0,x1,t0,zz,expmjd,expmjd-t0))
Пример #32
0
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))
Пример #33
0
    def _light_curves_from_query(self, cat_dict, query_result, grp, lc_per_field=None):

        t_dict = {}
        gamma_dict = {}
        m5_dict = {}
        t_min = None
        t_max = None
        for bp_name in cat_dict:
            self.lsstBandpassDict[bp_name].sbTophi()

            # generate a 2-D numpy array containing MJDs, m5, and photometric gamma values
            # for each observation in the given bandpass
            raw_array = np.array([[obs.mjd.TAI, obs.m5[bp_name],
                                   calcGamma(self.lsstBandpassDict[bp_name],
                                             obs.m5[obs.bandpass],
                                             self.phot_params)]
                                  for obs in grp if obs.bandpass == bp_name]).transpose()

            if len(raw_array) > 0:

                t_dict[bp_name] = raw_array[0]

                m5_dict[bp_name] = raw_array[1]

                gamma_dict[bp_name] = raw_array[2]

                local_t_min = t_dict[bp_name].min()
                local_t_max = t_dict[bp_name].max()
                if t_min is None or local_t_min < t_min:
                    t_min = local_t_min

                if t_max is None or local_t_max > t_max:
                    t_max = local_t_max

        snobj = SNObject()

        cat = cat_dict[list(cat_dict.keys())[0]]  # does not need to be associated with a bandpass

        dummy_sed = Sed()

        n_actual_sn = 0  # how many SN have we actually delivered?

        for chunk in query_result:

            if lc_per_field is not None and n_actual_sn >= lc_per_field:
                break

            t_start_chunk = time.time()
            for sn in cat.iter_catalog(query_cache=[chunk]):
                sn_rng = self.sn_universe.getSN_rng(sn[1])
                sn_t0 = self.sn_universe.drawFromT0Dist(sn_rng)
                if sn[5] <= self.z_cutoff and np.isfinite(sn_t0) and \
                    sn_t0 < t_max + cat.maxTimeSNVisible and \
                    sn_t0 > t_min - cat.maxTimeSNVisible:

                    sn_c = self.sn_universe.drawFromcDist(sn_rng)
                    sn_x1 = self.sn_universe.drawFromx1Dist(sn_rng)
                    sn_x0 = self.sn_universe.drawFromX0Dist(sn_rng, sn_x1, sn_c, sn[4])

                    snobj.set(t0=sn_t0, c=sn_c, x1=sn_x1, x0=sn_x0, z=sn[5])

                    for bp_name in t_dict:
                        t_list = t_dict[bp_name]
                        m5_list = m5_dict[bp_name]
                        gamma_list = gamma_dict[bp_name]
                        bandpass = self.lsstBandpassDict[bp_name]
                        if len(t_list) == 0:
                            continue

                        if snobj.maxtime() >= t_list[0] and snobj.mintime() <= t_list[-1]:
                            active_dexes = np.where(np.logical_and(t_list >= snobj.mintime(),
                                                                   t_list <= snobj.maxtime()))

                            t_active = t_list[active_dexes]
                            m5_active = m5_list[active_dexes]
                            gamma_active = gamma_list[active_dexes]

                            if len(t_active) > 0:

                                wave_ang = bandpass.wavelen*10.0
                                mask = np.logical_and(wave_ang > snobj.minwave(),
                                                      wave_ang < snobj.maxwave())

                                wave_ang = wave_ang[mask]
                                snobj.set(mwebv=sn[6])
                                sn_ff_buffer = snobj.flux(time=t_active, wave=wave_ang)*10.0
                                flambda_grid = np.zeros((len(t_active), len(bandpass.wavelen)))
                                for ff, ff_sn in zip(flambda_grid, sn_ff_buffer):
                                    ff[mask] = np.where(ff_sn > 0.0, ff_sn, 0.0)

                                fnu_grid = flambda_grid*bandpass.wavelen* \
                                           bandpass.wavelen*dummy_sed._physParams.nm2m* \
                                           dummy_sed._physParams.ergsetc2jansky/dummy_sed._physParams.lightspeed

                                flux_list = \
                                (fnu_grid*bandpass.phi).sum(axis=1)*(bandpass.wavelen[1]-bandpass.wavelen[0])

                                acceptable = np.where(flux_list>0.0)

                                flux_error_list = flux_list[acceptable]/ \
                                                  calcSNR_m5(dummy_sed.magFromFlux(flux_list[acceptable]),
                                                             bandpass,
                                                             m5_active[acceptable], self.phot_params,
                                                             gamma=gamma_active[acceptable])

                                if len(acceptable) > 0:

                                    n_actual_sn += 1
                                    if lc_per_field is not None and n_actual_sn > lc_per_field:
                                        break

                                    if sn[0] not in self.truth_dict:
                                        self.truth_dict[sn[0]] = {}
                                        self.truth_dict[sn[0]]['t0'] = sn_t0
                                        self.truth_dict[sn[0]]['x1'] = sn_x1
                                        self.truth_dict[sn[0]]['x0'] = sn_x0
                                        self.truth_dict[sn[0]]['c'] = sn_c
                                        self.truth_dict[sn[0]]['z'] = sn[5]
                                        self.truth_dict[sn[0]]['E(B-V)'] = sn[6]

                                    if sn[0] not in self.mjd_dict:
                                        self.mjd_dict[sn[0]] = {}
                                        self.bright_dict[sn[0]] = {}
                                        self.sig_dict[sn[0]] = {}

                                    if bp_name not in self.mjd_dict[sn[0]]:
                                        self.mjd_dict[sn[0]][bp_name] = []
                                        self.bright_dict[sn[0]][bp_name] = []
                                        self.sig_dict[sn[0]][bp_name] = []

                                for tt, ff, ee in zip(t_active[acceptable], flux_list[acceptable],
                                                      flux_error_list[0]):

                                    self.mjd_dict[sn[0]][bp_name].append(tt)
                                    self.bright_dict[sn[0]][bp_name].append(ff/3631.0)
                                    self.sig_dict[sn[0]][bp_name].append(ee/3631.0)

            print("chunk of ", len(chunk), " took ", time.time()-t_start_chunk)
Пример #34
0
        reschar = ResChar.fromSNCosmoRes(resfit)
        print('fit passed')
    except:
        reschar = 'failure'
        print('failed for SNID {0} with {1} points'.format(
            snid, len(lcinstance.snCosmoLC())))
    #if reschar != 'failure':
    #    pass
    #    fig = None#sncosmo.plot_lc(lcinstance.snCosmoLC(), model=(truth, reschar.sncosmoModel))
    return snid, lcinstance, reschar, truth, fig


snidvals = minion_params.index.values
print('The list of SN has {} SN'.format(len(snidvals)))

snmodel = SNObject(ra=30., dec=-30.)


def writevals(snid, fh):
    x = inferParams(snid,
                    snmodel,
                    paramsDF=minion_params,
                    lcsDF=minion,
                    infer_method=sncosmo.fit_lc,
                    minsnr=0.)
    if x[2] != 'failure':
        covs = map(str, x[2].covariance.values[np.triu_indices(4)])
        params = map(str, x[2].parameters.values)
        std = str(x[2].mu_variance_linear()**0.5)
        ss = ','.join(params + covs + [std])
        # print('cov = ' + ' '.join(covs))