示例#1
0
    def model_for_fit(self):

        #print 'there man, to fit'
        dust = sncosmo.OD94Dust()
        self.fit_model = 'salt2-extended'
        self.fit_version = '1.0'

        source = sncosmo.get_source(self.fit_model, version=self.fit_version)

        self.SN_fit_model = sncosmo.Model(source=source,
                                          effects=[dust, dust],
                                          effect_names=['host', 'mw'],
                                          effect_frames=['rest', 'obs'])

        self.SN_fit_model.set(z=self.z)
        self.SN_fit_model.set_source_peakabsmag(self.peakAbsMagBesselB,
                                                'bessellB',
                                                'vega',
                                                cosmo=cosmology.WMAP9)

        self.lsstmwebv = EBVbase()
        self.ebvofMW = self.lsstmwebv.calculateEbv(
            equatorialCoordinates=np.array([[np.radians(self.radeg)],
                                            [np.radians(self.decdeg)]]))[0]

        self.SN_fit_model.set(mwebv=self.ebvofMW)
        self.SN_fit_model.set(mwebv=0.)
示例#2
0
    def run_observation(self, dataSlice, slicePoint=None):

        #dataSlice = dataSlice[np.where(dataSlice[self.fieldID]==self.fieldID_ref)]
        self.fieldID_ref = dataSlice[self.fieldID][0]
        print 'Processing', self.fieldID_ref, len(dataSlice[self.fieldID])
        if len(dataSlice) > 0:
            dataSlice.sort(order=self.mjdCol)

            #print 'hello',dataSlice[self.fieldRA],len(dataSlice[self.fieldRA]),set(dataSlice[self.fieldRA]),len(set(dataSlice[self.fieldRA]))
            ra_field = list(set(dataSlice[self.fieldRA]))[0]
            dec_field = list(set(dataSlice[self.fieldDec]))[0]

            lsstmwebv = EBVbase()
            ebvofMW = lsstmwebv.calculateEbv(
                equatorialCoordinates=np.array([[ra_field], [dec_field]]))[0]

            dictout = {}

            dictout['ebvofMW'] = ebvofMW

            dictout['dataSlice'] = dataSlice

            outdir = self.outputdir.replace('Sim', 'Obs')
            #name_for_pkl=outdir+'/Observations_'+self.fieldName+'_'+str(int(self.fieldID_ref))+'_'+str(ra_field)+'_'+str(dec_field)
            name_for_pkl = outdir + '/Observations_' + self.fieldName + '_' + str(
                int(self.fieldID_ref))

            pkl_file = open(name_for_pkl + '.pkl', 'wb')

            pkl.dump(dictout, pkl_file)

            pkl_file.close()
        """
示例#3
0
    def testEBV(self):

        ebvObject = EBVbase()
        ra = []
        dec = []
        gLat = []
        gLon = []
        for i in range(10):
            ra.append(i*2.0*np.pi/10.0)
            dec.append(i*np.pi/10.0)

            gLat.append(-0.5*np.pi+i*np.pi/10.0)
            gLon.append(i*2.0*np.pi/10.0)

            equatorialCoordinates = np.array([ra, dec])
            galacticCoordinates = np.array([gLon, gLat])

        ebvOutput = ebvObject.calculateEbv(equatorialCoordinates=equatorialCoordinates)
        self.assertEqual(len(ebvOutput), len(ra))

        ebvOutput = ebvObject.calculateEbv(galacticCoordinates=galacticCoordinates)
        self.assertEqual(len(ebvOutput), len(gLon))
        self.assertGreater(len(ebvOutput), 0)

        self.assertRaises(RuntimeError, ebvObject.calculateEbv, equatorialCoordinates=equatorialCoordinates,
                          galacticCoordinates=galacticCoordinates)
        self.assertRaises(RuntimeError, ebvObject.calculateEbv,
                          equatorialCoordinates=None, galacticCoordinates=None)
        self.assertRaises(RuntimeError, ebvObject.calculateEbv)
    def testEBV(self):

        ebvObject = EBVbase()
        ra = []
        dec = []
        gLat = []
        gLon = []
        for i in range(10):
            ra.append(i * 2.0 * numpy.pi / 10.0)
            dec.append(i * numpy.pi / 10.0)

            gLat.append(-0.5 * numpy.pi + i * numpy.pi / 10.0)
            gLon.append(i * 2.0 * numpy.pi / 10.0)

            equatorialCoordinates = numpy.array([ra, dec])
            galacticCoordinates = numpy.array([gLon, gLat])

        ebvOutput = ebvObject.calculateEbv(equatorialCoordinates=equatorialCoordinates)
        self.assertEqual(len(ebvOutput), len(ra))

        ebvOutput = ebvObject.calculateEbv(galacticCoordinates=galacticCoordinates)
        self.assertEqual(len(ebvOutput), len(gLon))

        self.assertRaises(
            RuntimeError,
            ebvObject.calculateEbv,
            equatorialCoordinates=equatorialCoordinates,
            galacticCoordinates=galacticCoordinates,
        )
        self.assertRaises(RuntimeError, ebvObject.calculateEbv, equatorialCoordinates=None, galacticCoordinates=None)
        self.assertRaises(RuntimeError, ebvObject.calculateEbv)
    def __init__(self, ra=None, dec=None, source='salt2-extended'):
        """
        Instantiate object

        Parameters
        ----------
        ra : float
            ra of the SN in degrees
        dec : float
            dec of the SN in degrees

        source : instance of `sncosmo.SALT2Source`, optional, defaults to using salt2-extended 
            source class to define the model
        """

        dust = sncosmo.OD94Dust()
        sncosmo.Model.__init__(self, source=source, effects=[dust, dust],
                               effect_names=['host', 'mw'],
                               effect_frames=['rest', 'obs'])

        # Current implementation of Model has a default value of mwebv = 0.
        # ie. no extinction, but this is not part of the API, so should not
        # depend on it, set explicitly in order to unextincted SED from
        # SNCosmo. We will use catsim extinction from `lsst.sims.photUtils`.

        self.ModelSource = source
        self.set(mwebv=0.)

        # self._ra, self._dec is initialized as None for cases where ra, dec
        # is not provided
        self._ra = None
        self._dec = None

        # ra, dec is input in degrees
        # If provided, set _ra, _dec in radians
        self._hascoords = True
        if dec is None:
            self._hascoords = False
        if ra is None:
            self._hascoords = False

        # Satisfied that coordinates provided are floats
        if self._hascoords:
            self.setCoords(ra, dec)

        # For values of ra, dec, the E(B-V) is calculated directly
        # from DustMaps
        self.lsstmwebv = EBVbase()
        self.ebvofMW = None
        if self._hascoords:
            self.mwEBVfromMaps()
        return
示例#6
0
    def __init__(self, ra=None, dec=None, source='salt2-extended'):
        """
        Parameters
        ----------
        ra : float
            ra of the SN in degrees
        dec : float
            dec of the SN in degrees
        """
 
        dust = sncosmo.CCM89Dust()
        sncosmo.Model.__init__(self, source=source, effects=[dust, dust],
                               effect_names=['host', 'mw'], 
                               effect_frames=['rest', 'obs'])

        # Current implementation of Model has a default value of mwebv = 0.
        # ie. no extinction, but this is not part of the API, so should not
        # depend on it, set explicitly in order to unextincted SED from
        # SNCosmo. We will use catsim extinction from `lsst.sims.photUtils`.

        self.ModelSource = source
        self.set(mwebv=0.)


        # ra and dec if passed are assumed to be in degrees and converted into
        # radians.
        self._ra = ra
        self._dec = dec

        # NB: More lines of code to support the possibility that ra, dec are 
        # not provided at instantiation, and default to None
        self._hascoords = True
        if self._dec is None:
            self._hascoords = False
        if self._ra is None:
            self._hascoords = False

        # Satisfied that coordinates provided are floats
        if self._hascoords:
            self.setCoords(ra, dec)

        # For values of ra, dec, the E(B-V) is calculated directly
        # from DustMaps
        self.lsstmwebv = EBVbase()
        self.ebvofMW = None
        if self._hascoords:
            self.mwEBVfromMaps()
        return
class SNObject(sncosmo.Model):

    """
    Extension of the SNCosmo `TimeSeriesModel` to include more parameters and
    use methods in the catsim stack. We constrain ourselves to the use of a
    specific SALT model for the Supernova (Salt2-Extended), and set its MW
    extinction to be 0, since we will use the LSST software to calculate
    extinction.

    Parameters
    ----------
    ra : float
         ra of the SN in degrees
    dec : float
        dec of the SN in degrees


    Attributes
    ----------
    _ra : float or None
        ra of the SN in radians

    _dec : float or None
        dec of the SN in radians

    skycoord : `np.ndarray' of size 2 or None
        np.array([[ra], [dec]]), which are in radians

    ebvofMW : float or None
        mwebv value calculated from the self.skycoord if not None, or set to
        a value using self.set_MWebv. If neither of these are done, this value
        will be None, leading to exceptions in extinction calculation.
        Therefore, the value must be set explicitly to 0. to get unextincted
        quantities.

    Methods
    -------

    Examples
    --------
    >>> SNObject  = SNObject(ra=30., dec=60.)
    >>> SNObject._ra
    >>> 0.5235987755982988
    >>> SNObject._dec
    >>> 1.0471975511965976
    """

    def __init__(self, ra=None, dec=None, source='salt2-extended'):
        """
        Instantiate object

        Parameters
        ----------
        ra : float
            ra of the SN in degrees
        dec : float
            dec of the SN in degrees

        source : instance of `sncosmo.SALT2Source`, optional, defaults to using salt2-extended 
            source class to define the model
        """

        dust = sncosmo.OD94Dust()
        sncosmo.Model.__init__(self, source=source, effects=[dust, dust],
                               effect_names=['host', 'mw'],
                               effect_frames=['rest', 'obs'])

        # Current implementation of Model has a default value of mwebv = 0.
        # ie. no extinction, but this is not part of the API, so should not
        # depend on it, set explicitly in order to unextincted SED from
        # SNCosmo. We will use catsim extinction from `lsst.sims.photUtils`.

        self.ModelSource = source
        self.set(mwebv=0.)

        # self._ra, self._dec is initialized as None for cases where ra, dec
        # is not provided
        self._ra = None
        self._dec = None

        # ra, dec is input in degrees
        # If provided, set _ra, _dec in radians
        self._hascoords = True
        if dec is None:
            self._hascoords = False
        if ra is None:
            self._hascoords = False

        # Satisfied that coordinates provided are floats
        if self._hascoords:
            self.setCoords(ra, dec)

        # For values of ra, dec, the E(B-V) is calculated directly
        # from DustMaps
        self.lsstmwebv = EBVbase()
        self.ebvofMW = None
        if self._hascoords:
            self.mwEBVfromMaps()
        return

    @property
    def SNstate(self):
        """
        Dictionary summarizing the state of SNObject. Can be used to
        serialize to disk, and create SNObject from SNstate

        Returns : Dictionary with values of parameters of the model.
        """
        statedict = dict()

        # SNCosmo Parameters
        statedict['ModelSource'] = self.source.name
        for param_name in self.param_names:
            statedict[param_name] = self.get(param_name)

        # New Attributes
        # statedict['lsstmwebv'] = self.lsstmwebv
        statedict['_ra'] = self._ra
        statedict['_dec'] = self._dec
        statedict['MWE(B-V)'] = self.ebvofMW

        return statedict

    @classmethod
    def fromSNState(cls, snState):
        """
        creates an instance of SNObject with a state described by snstate.

        Parameters
        ----------
        snState: Dictionary summarizing the state of SNObject

        Returns
        -------
        Instance of SNObject class with attributes set by snstate

        Example
        -------

        """
        # Separate into SNCosmo parameters and SNObject parameters
        dust = sncosmo.OD94Dust()
        sncosmoModel = sncosmo.Model(source=snState['ModelSource'],
                                     effects=[dust, dust],
                                     effect_names=['host', 'mw'],
                                     effect_frames=['rest', 'obs'])

        sncosmoParams = cls.sncosmoParamDict(snState, sncosmoModel)

        # Now create the class
        cls = SNObject(source=snState['ModelSource'])

        # Set the SNObject coordinate properties
        # Have to be careful to not convert `None` type objects to degrees
        setdec, setra = False, False
        if snState['_ra'] is not None:
            ra = np.degrees(snState['_ra'])
            setra = True
        if snState['_dec'] is not None:
            dec = np.degrees(snState['_dec'])
            setdec = True
        if setdec and setra:
            cls.setCoords(ra, dec)

        # Set the SNcosmo parameters
        cls.set(**sncosmoParams)

        # Set the ebvofMW by hand
        cls.ebvofMW = snState['MWE(B-V)']

        return cls

    def equivalentSNCosmoModel(self):
        """
        returns an SNCosmo Model which is equivalent to SNObject
        """
        snState = self.SNstate
        dust = sncosmo.OD94Dust()
        sncosmoModel = sncosmo.Model(source=snState['ModelSource'],
                                     effects=[dust, dust],
                                     effect_names=['host', 'mw'],
                                     effect_frames=['rest', 'obs'])

        sncosmoParams = self.sncosmoParamDict(snState, sncosmoModel)
        sncosmoParams['mwebv'] = snState['MWE(B-V)']
        sncosmoModel.set(**sncosmoParams)
        return sncosmoModel
    @staticmethod
    def equivsncosmoParamDict(SNstate, SNCosmoModel):
        """
        return a dictionary that contains the parameters of SNCosmoModel
        that are contained in SNstate

        Parameters
        ----------
        SNstate : `SNObject.SNstate`, mandatory
            Dictionary defining the state of a SNObject
        SNCosmoModel : A `sncosmo.Model` instance, mandatory

        Returns
        -------
        sncosmoParams: Dictionary of sncosmo parameters

        """
        sncosmoParams = dict()
        for param in SNstate.keys():
            if param in SNCosmoModel.param_names:
                sncosmoParams[param] = SNstate[param]
        sncosmoParams['mwebv'] = SNstate['MWE(B-V)']
        return sncosmoParams

    @staticmethod
    def sncosmoParamDict(SNstate, SNCosmoModel):
        """
        return a dictionary that contains the parameters of SNCosmoModel
        that are contained in SNstate. Note that this does not return the
        equivalent SNCosmo  model.

        Parameters
        ----------
        SNstate : `SNObject.SNstate`, mandatory
            Dictionary defining the state of a SNObject
        SNCosmoModel : A `sncosmo.Model` instance, mandatory

        Returns
        -------
        sncosmoParams: Dictionary of sncosmo parameters

        """
        sncosmoParams = dict()
        for param in SNstate.keys():
            if param in SNCosmoModel.param_names:
                sncosmoParams[param] = SNstate[param]
        return sncosmoParams



    def summary(self):
        '''
        summarizes the current state of the SNObject class in a returned
        string.

        Parameters
        ----------
        None

        Returns
        -------
        Summary State in string format

        Examples
        --------
        >>> t = SNObject()
        >>> print t.summary()
        '''
        state = '  SNObject Summary      \n'

        state += 'Model = ' + '\n'
        state += 'z = ' + str(self.get('z')) + '\n'
        state += 'c = ' + str(self.get('c')) + '\n'
        state += 'x1 = ' + str(self.get('x1')) + '\n'
        state += 'x0 = ' + str(self.get('x0')) + '\n'
        state += 't0 = ' + str(self.get('t0')) + '\n'
        state += 'ra = ' + str(self._ra) + ' in radians \n'
        state += 'dec = ' + str(self._dec) + ' in radians \n'
        state += 'MW E(B-V) = ' + str(self.ebvofMW) + '\n'

        return state

    def setCoords(self, ra, dec):
        """
        set the ra and dec coordinate of SNObject to values in radians
        corresponding to the given values in degrees

        Parameters
        ----------
        ra: float, mandatory
            the ra in degrees
        dec: float, mandatory
            dec in degrees

        Returns
        -------
        None

        Examples
        --------
        >>> t = SNObject()
        >>> t.setCoords(ra=30., dec=90.)
        >>> t._ra
        >>> 0.5235987755982988
        >>> t._dec
        >>> 1.0471975511965976
        """

        if ra is None or dec is None:
            raise ValueError('Why try to set coordinates without full'
                             'coordiantes?\n')
        self._ra = np.radians(ra)
        self._dec = np.radians(dec)
        self.skycoord = np.array([[self._ra], [self._dec]])

        self._hascoords = True

        return

    def set_MWebv(self, value):
        """
        if mwebv value is known, this can be used to set the attribute
        ebvofMW of the SNObject class to the value (float).

        Parameters
        ----------
        value: float, mandatory
               value of mw extinction parameter E(B-V) in mags to be used in
               applying extinction to the SNObject spectrum

        Returns
        -------
        None

        Examples
        --------
        >>> t = SNObject()
        >>> t.set_MWebv(0.)
        >>> 0.
        """
        self.ebvofMW = value
        return

    def mwEBVfromMaps(self):
        """
        set the attribute ebvofMW of the class from the ra and dec
        of the SN. If the ra or dec attribute of the class is None,
        set this attribute to None.

        Parameters
        ----------
        None

        Returns
        -------
        None

        Examples
        --------
        >>> t = SNObject()
        >>> t.setCoords(ra=30., dec=60.)
        >>> t.mwEBVfromMaps()
        >>> t.ebvofMW
        >>> 0.977767825127

        .. note:: This function must be run after the class has attributes ra
                  and dec set. In case it is run before this, the mwebv value
                  will be set to None.

        """

        if not self._hascoords:
            raise ValueError('Cannot Calculate EBV from dust maps if ra or dec'
                             'is `None`')
        self.ebvofMW = self.lsstmwebv.calculateEbv(
            equatorialCoordinates=self.skycoord)[0]
        return

    def SNObjectSED(self, time, wavelen=None, bandpass=None,
                    applyExtinction=True):
        '''
        return a `lsst.sims.photUtils.sed` object from the SN model at the
        requested time and wavelengths with or without extinction from MW
        according to the SED extinction methods. The wavelengths may be
        obtained from a `lsst.sims.Bandpass` object or a `lsst.sims.BandpassDict`
        object instead. (Currently, these have the same wavelengths). See notes
        for details on handling of exceptions.

        If the sed is requested at times outside the validity range of the
        model, the flux density is returned as 0. If the time is within the
        range of validity of the model, but the wavelength range requested
        is outside the range, then the returned fluxes are np.nan outside
        the range, and the model fluxes inside

        Parameters
        ----------
        time: float
            time of observation
        wavelen: `np.ndarray` of floats, optional, defaults to None
            array containing wavelengths in nm
        bandpass: `lsst.sims.photUtils.Bandpass` object or
            `lsst.sims.photUtils.BandpassDict`, optional, defaults to `None`.
            Using the dict assumes that the wavelength sampling and range
            is the same for all elements of the dict.

            if provided, overrides wavelen input and the SED is
            obtained at the wavelength values native to bandpass
            object.


        Returns
        -------
        `sims_photutils.sed` object containing the wavelengths and SED
        values from the SN at time time in units of ergs/cm^2/sec/nm


        .. note: If both wavelen and bandpassobject are `None` then exception,
                 will be raised.
        Examples
        --------
        >>> sed = SN.SNObjectSED(time=0., wavelen=wavenm)
        '''

        if wavelen is None and bandpass is None:
            raise ValueError('A non None input to either wavelen or\
                              bandpassobject must be provided')

        # if bandpassobject present, it overrides wavelen
        if bandpass is not None:
            if isinstance(bandpass, BandpassDict):
                firstfilter = bandpass.keys()[0]
                bp = bandpass[firstfilter]
            else:
                bp = bandpass
            # remember this is in nm
            wavelen = bp.wavelen

        flambda = np.zeros(len(wavelen))

        # self.mintime() and self.maxtime() are properties describing
        # the ranges of SNCosmo.Model in time.

        # Set SED to 0 beyond the model phase range, will change this if
        # SNCosmo includes a more sensible decay later.
        if (time > self.mintime()) & (time < self.maxtime()):

            # If SNCosmo is requested a SED value beyond the model range
            # it will crash. Try to prevent that by returning np.nan for
            # such wavelengths. This will still not help band flux calculations
            # but helps us get past this stage.

            flambda = flambda * np.nan

            # Convert to Ang
            wave = wavelen * 10.0
            mask1 = wave > self.minwave()
            mask2 = wave < self.maxwave()
            mask = mask1 & mask2
            wave = wave[mask]

            # flux density dE/dlambda returned from SNCosmo in
            # ergs/cm^2/sec/Ang, convert to ergs/cm^2/sec/nm

            flambda[mask] = self.flux(time=time, wave=wave)
            flambda[mask] = flambda[mask] * 10.0

        SEDfromSNcosmo = Sed(wavelen=wavelen, flambda=flambda)

        if not applyExtinction:
            return SEDfromSNcosmo

        # Apply LSST extinction
        ax, bx = SEDfromSNcosmo.setupCCMab()

        if self.ebvofMW is None:
            raise ValueError('ebvofMW attribute cannot be None Type and must'
                             ' be set by hand using set_MWebv before this'
                             'stage, or by using setcoords followed by'
                             'mwEBVfromMaps\n')

        SEDfromSNcosmo.addCCMDust(a_x=ax, b_x=bx, ebv=self.ebvofMW)
        return SEDfromSNcosmo

    def catsimBandFlux(self, time, bandpassobject):
        """
        return the flux in the bandpass in units of maggies which is the flux
        the AB magnitude reference spectrum would have in the same band.

        Parameters
        ----------
        time: mandatory, float
            MJD at which band fluxes are evaluated
        bandpassobject: mandatory, `lsst.sims.photUtils.BandPass` object
            A particular bandpass which is an instantiation of one of
            (u, g, r, i, z, y)
        Returns
        -------
        float value for flux in band in units of maggies

        Examples
        --------
        >>> bandpassnames = ['u', 'g', 'r', 'i', 'z', 'y']
        >>> LSST_BandPass = BandpassDict.loadTotalBandpassesFromFiles()
        >>> SN = SNObject(ra=30., dec=-60.)
        >>> SN.set(z=0.96, t0=571181, x1=2.66, c=0.353, x0=1.796112e-06)
        >>> SN.catsimBandFlux(bandpassobject=LSST_BandPass['r'], time=571190.)
        >>> 1.9856857972304903e-11

        .. note: If there is an unphysical value of sed in
        the wavelength range, it produces a flux of  `np.nan`
        """
        SEDfromSNcosmo = self.SNObjectSED(time=time,
                                          bandpass=bandpassobject)
        return SEDfromSNcosmo.calcFlux(bandpass=bandpassobject) / 3631.0
 
    def catsimBandMag(self, bandpassobject, time, fluxinMaggies=None):
        """
        return the magnitude in the bandpass in the AB magnitude system

        Parameters
        ----------
        bandpassobject : mandatory,`sims.photUtils.BandPass` instances
            LSST Catsim bandpass instance for a particular bandpass
        time : mandatory, float
            MJD at which this is evaluated
        Returns
        -------
        float value of band magnitude in AB system

        Examples
        --------
        """
        if fluxinMaggies is None:
            fluxinMaggies = self.catsimBandFlux(bandpassobject=bandpassobject,
                                                time=time)
        return -2.5 * np.log10(fluxinMaggies)

    def catsimBandFluxError(self, time, bandpassobject, m5,
                            fluxinMaggies=None,
                            magnitude=None,
                            photParams=None):
        """
        return the flux uncertainty in the bandpass in units 'maggies'
        (the flux the AB magnitude reference spectrum would have in the
        same band.)

        Parameters
        ----------
        time: mandatory, float
            MJD at which band fluxes are evaluated
        bandpassobject: mandatory, `lsst.sims.photUtils.BandPass` object
            A particular bandpass which is an instantiation of one of
            (u, g, r, i, z, y)
        m5 :
        photParams :
        magnitude :
        Returns
        -------
        float

        Examples
        --------
        .. note: If there is an unphysical value of sed in
        the wavelength range, it produces a flux of  `np.nan`
        """
        if fluxinMaggies is None:
            fluxinMaggies = self.catsimBandFlux(time=time,
                                                bandpassobject=bandpassobject)
        if magnitude is None:
            mag = self.catsimBandMag(time=time, fluxinMaggies=fluxinMaggies,
                                     bandpassobject=bandpassobject)
        else:
            mag = magnitude

        if photParams is None:
            photParams = PhotometricParameters()

        SNR, gamma = calcSNR_m5(magnitude=mag, bandpass=bandpassobject,
                                m5=m5, photParams=photParams)
        return fluxinMaggies / SNR

    def catsimBandMagError(self, time, bandpassobject, m5, photParams=None,
                           magnitude=None):
        """
        return the 68 percent uncertainty on the magnitude in the bandpass

        Parameters
        ----------
        time: mandatory, float
            MJD at which band fluxes are evaluated
        bandpassobject: mandatory, `lsst.sims.photUtils.BandPass` object
            A particular bandpass which is an instantiation of one of
            (u, g, r, i, z, y)
        m5 :
        photParams :
        magnitude :

        Returns
        -------
        float

        Examples
        --------
        .. note: If there is an unphysical value of sed in
        the wavelength range, it produces a flux of  `np.nan`
        """

        if magnitude is None:
            mag = self.catsimBandMag(time=time,
                                     bandpassobject=bandpassobject)
        else:
            mag = magnitude

        bandpass = bandpassobject

        if photParams is None:
            photParams = PhotometricParameters()

        magerr = calcMagError_m5(magnitude=mag,
                                 bandpass=bandpassobject,
                                 m5=m5,
                                 photParams=photParams)
        return magerr[0]


    def catsimManyBandFluxes(self, time, bandpassDict,
                             observedBandPassInd=None):
        """
        return the flux in the multiple bandpasses of a bandpassDict
        indicated by observedBandPassInd in units of maggies

        Parameters
        ----------
        time: mandatory, float
            MJD at which band fluxes are evaluated
        bandpassDict: mandatory, `lsst.sims.photUtils.BandpassDict` instance
        observedBandPassInd : optional, list of integers, defaults to None
            integer correspdonding to index of the bandpasses used in the
            observation in the ordered dict bandpassDict
        Returns
        -------
        `~numpy.ndarray` of length =len(observedBandPassInd)

        Examples
        --------
        .. note: If there is an unphysical value of sed in
        the wavelength range, it produces a flux of  `np.nan`
        """
        SEDfromSNcosmo = self.SNObjectSED(time=time,
                                          bandpass=bandpassDict['u'])
        wavelen_step = np.diff(SEDfromSNcosmo.wavelen)[0]
        SEDfromSNcosmo.flambdaTofnu()
        f = SEDfromSNcosmo.manyFluxCalc(bandpassDict.phiArray,
                                        wavelen_step=wavelen_step,
                                        observedBandpassInd=observedBandPassInd)
        return f / 3631.

    def catsimManyBandMags(self, time, bandpassDict,
                           observedBandPassInd=None):
        """
        return the flux in the bandpass in units of the flux
        the AB magnitude reference spectrum would have in the
        same band.

        Parameters
        ----------
        time: mandatory, float
            MJD at which band fluxes are evaluated
        bandpassDict: mandatory, `lsst.sims.photUtils.BandpassDict` instance
        observedBandPassInd : optional, list of integers, defaults to None
            integer correspdonding to index of the bandpasses used in the
            observation in the ordered dict bandpassDict
        Returns
        -------
        `~numpy.ndarray` of length =len(observedBandPassInd)

        Examples
        --------
        .. note: If there is an unphysical value of sed in
        the wavelength range, it produces a flux of  `np.nan`
        """
        f = self.catsimManyBandFluxes(time,
                                      bandpassDict,
                                      observedBandPassInd)

        return -2.5 * np.log10(f)


    def catsimManyBandADUs(self, time, bandpassDict,
                  photParams=None,
                  observedBandPassInds=None):
        """
        time: float, mandatory
            MJD of the observation

        bandpassDict: mandatory,
            Dictionary of instances of `sims.photUtils.Bandpass` for
            filters

        photParams: Instance of `sims.photUtils.PhotometricParameters`, optional,
                    defaults to None
                    Describes the observational parameters used in specifying the
                    photometry of the ovservation
        observedBandPassInd: None
            Not used now
        """
        SEDfromSNcosmo = self.SNObjectSED(time=time,
                                          bandpass=bandpassDict)

        bandpassNames = bandpassDict.keys()
        adus = np.zeros(len(bandpassNames))

        for i, filt in enumerate(bandpassNames):
            bandpass = bandpassDict[filt]
            adus[i] = SEDfromSNcosmo.calcADU(bandpass, photParams=photParams)

        return adus
示例#8
0
    def __init__(self,
                 ra,
                 dec,
                 z,
                 t0,
                 c=0,
                 x1=0,
                 peakAbsMagBesselB=-19.0906,
                 model='salt2-extended',
                 version='1.0',
                 sn_type='Ia',
                 mwdust=True):
        self.radeg = ra
        self.decdeg = dec
        self.z = z
        self.t0 = t0
        self.c = c
        self.x1 = x1
        self.peakAbsMagBesselB = peakAbsMagBesselB
        self.model = model
        self.version = version
        self.sn_type = sn_type
        self.id_SED = ''
        self.cosmology = cosmology.WMAP9
        self.cosmology = FlatLambdaCDM(H0=70, Om0=0.25)
        astropy_cosmo = FlatLambdaCDM(H0=self.cosmology.H0,
                                      Om0=self.cosmology.Om0)
        self.lumidist = astropy_cosmo.luminosity_distance(self.z).value * 1.e6
        #print 'SN Lumidist',self.lumidist,self.cosmology.H0,self.cosmology.Om0

        #print 'sntype',self.sn_type
        dust = sncosmo.OD94Dust()
        self.lsstmwebv = EBVbase()
        self.ebvofMW = self.lsstmwebv.calculateEbv(
            equatorialCoordinates=np.array([[np.radians(self.radeg)],
                                            [np.radians(self.decdeg)]]))[0]

        if self.sn_type == 'Ia':

            if version == '':
                source = sncosmo.get_source(self.model)
            else:
                source = sncosmo.get_source(self.model, version=self.version)

            self.SN = sncosmo.Model(source=source,
                                    effects=[dust, dust],
                                    effect_names=['host', 'mw'],
                                    effect_frames=['rest', 'obs'])

            #self.SN=sncosmo.Model(source=self.source)

            #self.SN=sncosmo.Model(source=self.source)

            #print 'blabla',self.SN.minwave(),self.SN.maxwave()
            lowrange = -30.
            highrange = 50.

            self.SN.set(z=self.z)
            self.SN.set(t0=self.t0)
            self.SN.set(c=self.c)
            self.SN.set(x1=self.x1)

            self.SN.set_source_peakabsmag(self.peakAbsMagBesselB,
                                          'bessellB',
                                          'vega',
                                          cosmo=self.cosmology)

            #self.SN.set(mwebv=self.ebvofMW)
            #self.SN.set(mwebv=0.)

        else:
            self.Fill_nonIa_ID()
            resu = self.Get_nonIa_Template_ID()
            #id_SED='SDSS-018109'
            #id_SED='SDSS-018457'
            """
            if id_SED != None:
                self.id_SED=id_SED
                print 'tagged',self.id_SED
                #self.SED_all_phases=self.Load_SED('NON1A/'+id_SED+'.SED')
                phase, wave, values = read_griddata_ascii('NON1A/'+id_SED+'.SED')
                print 'min max',np.min(wave),np.max(wave)
                self.SED_template = Spline2d(phase, wave, values, kx=2, ky=2)
            """

            self.model = thename = resu[0]
            self.version = resu[1]

            #print 'the choice',resu[0],resu[1]
            """
            thename='snana-2007kw' 
            theversion='1.0'
            """

            if thename != None:

                #print 'Getting the source'
                source = sncosmo.get_source(self.model, self.version)
                #print 'Getting the model'
                self.SN = sncosmo.Model(source=source,
                                        effects=[dust, dust],
                                        effect_names=['host', 'mw'],
                                        effect_frames=['rest', 'obs'])

                #print 'Setting z and T0'
                self.SN.set(z=self.z)
                self.SN.set(t0=self.t0)
                #print 'SN here',self.z,self.t0,thename,theversion
                self.SN.set_source_peakabsmag(-18.,
                                              'bessellB',
                                              'vega',
                                              cosmo=self.cosmology)
        #MW extinction
        if mwdust:
            self.SN.set(mwebv=self.ebvofMW)
            self.SN.set(mwebv=0.)

        self.model_for_fit()
示例#9
0
class SN_Object:
    def __init__(self,
                 ra,
                 dec,
                 z,
                 t0,
                 c=0,
                 x1=0,
                 peakAbsMagBesselB=-19.0906,
                 model='salt2-extended',
                 version='1.0',
                 sn_type='Ia',
                 mwdust=True):
        self.radeg = ra
        self.decdeg = dec
        self.z = z
        self.t0 = t0
        self.c = c
        self.x1 = x1
        self.peakAbsMagBesselB = peakAbsMagBesselB
        self.model = model
        self.version = version
        self.sn_type = sn_type
        self.id_SED = ''
        self.cosmology = cosmology.WMAP9
        self.cosmology = FlatLambdaCDM(H0=70, Om0=0.25)
        astropy_cosmo = FlatLambdaCDM(H0=self.cosmology.H0,
                                      Om0=self.cosmology.Om0)
        self.lumidist = astropy_cosmo.luminosity_distance(self.z).value * 1.e6
        #print 'SN Lumidist',self.lumidist,self.cosmology.H0,self.cosmology.Om0

        #print 'sntype',self.sn_type
        dust = sncosmo.OD94Dust()
        self.lsstmwebv = EBVbase()
        self.ebvofMW = self.lsstmwebv.calculateEbv(
            equatorialCoordinates=np.array([[np.radians(self.radeg)],
                                            [np.radians(self.decdeg)]]))[0]

        if self.sn_type == 'Ia':

            if version == '':
                source = sncosmo.get_source(self.model)
            else:
                source = sncosmo.get_source(self.model, version=self.version)

            self.SN = sncosmo.Model(source=source,
                                    effects=[dust, dust],
                                    effect_names=['host', 'mw'],
                                    effect_frames=['rest', 'obs'])

            #self.SN=sncosmo.Model(source=self.source)

            #self.SN=sncosmo.Model(source=self.source)

            #print 'blabla',self.SN.minwave(),self.SN.maxwave()
            lowrange = -30.
            highrange = 50.

            self.SN.set(z=self.z)
            self.SN.set(t0=self.t0)
            self.SN.set(c=self.c)
            self.SN.set(x1=self.x1)

            self.SN.set_source_peakabsmag(self.peakAbsMagBesselB,
                                          'bessellB',
                                          'vega',
                                          cosmo=self.cosmology)

            #self.SN.set(mwebv=self.ebvofMW)
            #self.SN.set(mwebv=0.)

        else:
            self.Fill_nonIa_ID()
            resu = self.Get_nonIa_Template_ID()
            #id_SED='SDSS-018109'
            #id_SED='SDSS-018457'
            """
            if id_SED != None:
                self.id_SED=id_SED
                print 'tagged',self.id_SED
                #self.SED_all_phases=self.Load_SED('NON1A/'+id_SED+'.SED')
                phase, wave, values = read_griddata_ascii('NON1A/'+id_SED+'.SED')
                print 'min max',np.min(wave),np.max(wave)
                self.SED_template = Spline2d(phase, wave, values, kx=2, ky=2)
            """

            self.model = thename = resu[0]
            self.version = resu[1]

            #print 'the choice',resu[0],resu[1]
            """
            thename='snana-2007kw' 
            theversion='1.0'
            """

            if thename != None:

                #print 'Getting the source'
                source = sncosmo.get_source(self.model, self.version)
                #print 'Getting the model'
                self.SN = sncosmo.Model(source=source,
                                        effects=[dust, dust],
                                        effect_names=['host', 'mw'],
                                        effect_frames=['rest', 'obs'])

                #print 'Setting z and T0'
                self.SN.set(z=self.z)
                self.SN.set(t0=self.t0)
                #print 'SN here',self.z,self.t0,thename,theversion
                self.SN.set_source_peakabsmag(-18.,
                                              'bessellB',
                                              'vega',
                                              cosmo=self.cosmology)
        #MW extinction
        if mwdust:
            self.SN.set(mwebv=self.ebvofMW)
            self.SN.set(mwebv=0.)

        self.model_for_fit()

    def get_SEDb(self, time):

        if self.sn_type == 'Ia':

            if self.model == 'salt2' and self.version == '2.4':
                model_min = 2000.
                model_max = 9200.0
                wave_min = model_min * (1. + self.z)
                wave_max = model_max * (1. + self.z)

            if self.model == 'salt2-extended':
                model_min = 300.
                model_max = 180000.
                wave_min = 3000.
                wave_max = 11501.

            wave = np.arange(wave_min, wave_max, 1.)
            fluxes = 10. * self.SN.flux(time, wave)
            #self.wavelength=wave/10.
            return fluxes

    def get_SED(self, time):

        if self.sn_type == 'Ia':

            if self.model == 'salt2' and self.version == '2.4':
                model_min = 2000.
                model_max = 9200.0
                wave_min = model_min * (1. + self.z)
                wave_max = model_max * (1. + self.z)

            if self.model == 'salt2-extended':
                model_min = 300.
                model_max = 180000.
                wave_min = 3000.
                wave_max = 11501.

            wave = np.arange(wave_min, wave_max, 1.)
            self.fluxes = 10. * self.SN.flux(time, wave)
            self.wavelength = wave / 10.

            #SED_time = 10.*self.SN.flux(time,wave)
            #print 'hohoho',len(self.wavelength),len(self.fluxes),type(self.wavelength)
            wavelength = np.repeat(self.wavelength[np.newaxis, :],
                                   len(self.fluxes), 0)
            #print 'hrlll',len(wavelength),type(wavelength[0])

            SED_time = Sed(wavelen=wavelength, flambda=self.fluxes)
            """
            ax, bx = self.SEDfromSNcosmo.setupCCMab()
            self.SEDfromSNcosmo.addCCMDust(a_x=ax, b_x=bx, ebv=self.ebvofMW)
            """

        else:
            wave_min = 3000.
            wave_max = 11501.
            wave = np.arange(wave_min, wave_max, 1.)

            #print 'getting the flux'
            self.fluxes = 10. * self.SN.flux(time, wave)
            self.wavelength = wave / 10.

            #SED_time = Sed(wavelen=self.wavelength, flambda=self.fluxes/np.power(self.lumidist,2.))
            #/np.power(self.lumidist,2.))

            SED_time = Sed(wavelen=self.wavelength, flambda=self.fluxes)
            """
            a=1./(1.+self.z)
            phase=(time-self.t0)*a
            restwave=wave*a
            flambda=self.SED_template(phase, restwave)[0]
            #print 'alors',len(wave),len(flambda),flambda
           
            SED_time=Sed(wavelen=wave/10., flambda=10.*a*flambda /np.power(self.lumidist,2.))
            """

        return SED_time

    def Load_SED(self, filename):

        sfile = open(filename, 'r')
        mytype = [('phase', np.float), ('wavelength', np.float),
                  ('flambda', np.float)]
        tab_sed = np.zeros((60, 1), dtype=[type for type in mytype])

        inum = -1
        for line in sfile.readlines():
            if line[0] != '#':
                thesplb = line.split(' ')
                thespl = [spl for spl in thesplb if spl != '']
                #print 'hello pal',thespl
                phase = float(thespl[0])
                wave = float(thespl[1])
                flambda = float(thespl[2].strip())
                inum += 1
                if len(tab_sed) <= inum:
                    tab_sed = np.resize(tab_sed, (len(tab_sed) + 100, 1))

                tab_sed['phase'][inum] = phase
                tab_sed['wavelength'][inum] = wave
                tab_sed['flambda'][inum] = flambda

        return np.resize(tab_sed, (inum + 1, 1))

    def model_for_fit(self):

        #print 'there man, to fit'
        dust = sncosmo.OD94Dust()
        self.fit_model = 'salt2-extended'
        self.fit_version = '1.0'

        source = sncosmo.get_source(self.fit_model, version=self.fit_version)

        self.SN_fit_model = sncosmo.Model(source=source,
                                          effects=[dust, dust],
                                          effect_names=['host', 'mw'],
                                          effect_frames=['rest', 'obs'])

        self.SN_fit_model.set(z=self.z)
        self.SN_fit_model.set_source_peakabsmag(self.peakAbsMagBesselB,
                                                'bessellB',
                                                'vega',
                                                cosmo=cosmology.WMAP9)

        self.lsstmwebv = EBVbase()
        self.ebvofMW = self.lsstmwebv.calculateEbv(
            equatorialCoordinates=np.array([[np.radians(self.radeg)],
                                            [np.radians(self.decdeg)]]))[0]

        self.SN_fit_model.set(mwebv=self.ebvofMW)
        self.SN_fit_model.set(mwebv=0.)

    def Fill_nonIa_ID(self):

        self.dict_nonIa = {}
        #filename='NON1A/NON1A.LIST'
        filename = 'NON1A.list'
        sfile = open(filename, 'r')

        for line in sfile.readlines():
            #print 'hello line',line,line.count('NONIA:')
            #if line.count('NON1A:') > 0:

            thesplb = line.split(' ')
            thespl = [spl for spl in thesplb if spl != '']
            thename = thespl[0].strip()
            thetype = thespl[2].strip()
            theversion = thespl[1].strip()
            if self.dict_nonIa.has_key(thetype):
                self.dict_nonIa[thetype].append((thename, theversion))
            else:
                self.dict_nonIa[thetype] = []
                self.dict_nonIa[thetype].append((thename, theversion))

    def Fill_nonIa_ID_mine(self):

        self.dict_nonIa = {}
        filename = 'NON1A/NON1A.LIST'
        #filename='NON1A.list'
        sfile = open(filename, 'r')

        for line in sfile.readlines():
            #print 'hello line',line,line.count('NONIA:')
            if line.count('NON1A:') > 0:

                thesplb = line.split(' ')
                thespl = [spl for spl in thesplb if spl != '']
                thename = thespl[2].strip()
                thetype = thespl[1].strip()
                if self.dict_nonIa.has_key(thetype):
                    self.dict_nonIa[thetype].append(thename)
                else:
                    self.dict_nonIa[thetype] = []
                    self.dict_nonIa[thetype].append(thename)

    def Get_nonIa_Template_ID(self):

        if not self.dict_nonIa.has_key(self.sn_type):
            print 'problem here - SN type not valid'
            print 'Possible SN types', self.dict_nonIa.keys()
            return None
        else:

            choose = np.random.randint(0, len(self.dict_nonIa[self.sn_type]))
            #print 'result',choose,self.dict_nonIa[self.sn_type][choose]
            return self.dict_nonIa[self.sn_type][choose]

    def Get_SED_Restframe(self, Sed_time):

        a = 1. / (1. + self.z)
        bandpass_besselb = Bandpass(
            wavelen=sncosmo.get_bandpass('bessellB').wave,
            sb=sncosmo.get_bandpass('bessellB').trans)
        print 'before', Sed_time.wavelen, Sed_time.flambda
        #print 'there we go',Sed_time.wavelen,Sed_time.flambda
        SED_rest = Sed(wavelen=Sed_time.wavelen * a * 10.,
                       flambda=Sed_time.flambda * np.power(self.lumidist, 2.) /
                       a / 10. / HC_ERG_AA)
        print 'hello', Sed_time.wavelen * a * 10, Sed_time.flambda * np.power(
            self.lumidist, 2.) / a / 10. / HC_ERG_AA
        print 'heelp', SED_rest.wavelen, SED_rest.flambda

        SED_new = Sed(wavelen=SED_rest.wavelen / a,
                      flambda=a * SED_rest.flambda /
                      np.power(self.lumidist, 2.))
        #print 'ici',SED_new.wavelen,SED_new.flambda
        #estimate the flux in the B band bessellb

        flux_B_rest = SED_rest.calcFlux(bandpass=bandpass_besselb)
        flux_B_new = SED_new.calcFlux(bandpass=bandpass_besselb)
        #now the magnitudes (apparent and absolute)

        vega_SED = Sed()

        vega_SED.readSED_flambda('vega.txt')
        flux_vega = vega_SED.calcFlux(bandpass=bandpass_besselb)

        mag_B_rest = -2.5 * np.log10(flux_B_rest / flux_vega)
        mag_B_new = -2.5 * np.log10(flux_B_new / 3631.)

        print 'hello', len(vega_SED.wavelen), len(vega_SED.flambda), len(
            bandpass_besselb.sb), flux_vega, flux_B_rest

        bwave = bandpass_besselb.wavelen
        btrans = bandpass_besselb.sb
        vega_wave = vega_SED.wavelen
        vega_flambda = vega_SED.flambda

        mask = ((vega_wave > bwave[0]) & (vega_wave < bwave[-1]))
        d = vega_wave[mask]
        f = vega_flambda[mask]

        trans = np.interp(d, bwave, btrans)
        binw = np.gradient(d)
        ftot = np.sum(f * trans * binw)

        print 'vega flux', flux_vega, ftot
        return SED_rest, mag_B_rest, mag_B_new
示例#10
0
    def __init__(self,
                 parameters,
                 fit=False,
                 model='salt2-extended',
                 version='1.0',
                 telescope=None,
                 ra=6.0979440,
                 dec=-1.1051600,
                 airmass=1.2,
                 X0=None,
                 dL=None):

        #time_begin=time.time()

        self.lc = []
        self.m5 = {
            'u': 23.61,
            'g': 24.83,
            'r': 24.35,
            'i': 23.88,
            'z': 23.30,
            'y': 22.43
        }
        self.radeg = np.rad2deg(ra)
        self.decdeg = np.rad2deg(dec)

        self.model = model
        self.version = version

        self.peakAbsMagBesselB = -19.0906

        if self.model == 'salt2-extended':
            model_min = 300.
            model_max = 180000.
            wave_min = 3000.
            wave_max = 11501.

        if self.model == 'salt2':
            model_min = 3400.
            model_max = 11501.
            wave_min = model_min
            wave_max = model_max

        self.wave = np.arange(wave_min, wave_max, 1.)

        self.sn_type = 'Ia'

        source = sncosmo.get_source(self.model, version=self.version)
        #self.mycosmology=FlatLambdaCDM(H0=70, Om0=0.25)
        #astropy_cosmo=FlatLambdaCDM(H0= self.mycosmology.H0, Om0=self.mycosmology.Om0)

        dust = sncosmo.OD94Dust()

        #self.transmission=Throughputs(through_dir='FAKE_THROUGH',atmos_dir='FAKE_THROUGH',atmos=False,aerosol=False)

        self.transmission = telescope.throughputs
        #self.transmission.Load_Atmosphere(airmass)
        #print 'total elapse time init a',time.time()-time_begin
        self.telescope = telescope
        """
        for band in self.bands:
            themax=np.max(self.transmission.lsst_system[band].sb)
            idx = self.transmission.lsst_system[band].sb >= 0.2*themax
            sel=self.transmission.lsst_system[band].wavelen[idx]
            print band,np.min(sel),np.max(sel)
        """
        """
        self.airmass=airmass
        if self.airmass > 0:
            self.transmission.Load_Atmosphere(airmass)
        """
        #self.lc={}
        #print 'there we go',parameters,len(parameters),parameters.dtype

        self.param = parameters
        """
        SN=sncosmo.Model(source=source,effects=[dust, dust],
                         effect_names=['host', 'mw'],
                         effect_frames=['rest', 'obs'])
        """
        self.SN = sncosmo.Model(source=source)

        self.z = self.param['z']
        if X0 is None:
            self.Cosmology()
            lumidist = self.astropy_cosmo.luminosity_distance(
                self.param['z']).value * 1.e3
            self.dL = lumidist
            #X0_snsim = self.X0_norm_snsim() / lumidist** 2
            X0 = self.X0_norm() / lumidist**2
            #print 'before alpha beta',X0
            alpha = 0.13
            beta = 3.
            X0 *= np.power(
                10.,
                0.4 * (alpha * self.param['X1'] - beta * self.param['Color']))
            self.X0 = X0

        else:
            self.X0 = X0
            self.dL = dL
        #print 'llla',X0,alpha,beta,param['X1'],param['Color'],param['z'],lumidist
        #self.X0=X0
        #print 'hello x0',X0,lumidist
        #SN=sncosmo.Model(source=source)
        self.SN.set(z=self.param['z'])
        self.SN.set(t0=self.param['DayMax'])
        self.SN.set(c=self.param['Color'])
        self.SN.set(x1=self.param['X1'])
        self.SN.set(x0=self.X0)

        #print 'total elapse time init b',time.time()-time_begin

        #self.SED={}
        #print 'sncosmo parameters',self.SN.param_names,self.SN.parameters
        lsstmwebv = EBVbase()

        ebvofMW = lsstmwebv.calculateEbv(equatorialCoordinates=np.array(
            [[np.radians(self.radeg)], [np.radians(self.decdeg)]]))[0]
        #self.SN.set(mwebv=ebvofMW)

        #self.SN.set_source_peakabsmag(self.peakAbsMagBesselB, 'bessellB', 'vega',cosmo=self.astropy_cosmo)
        if self.sn_type == 'Ia':
            self.mbsim = self.SN._source.peakmag('bessellb', 'vega')
示例#11
0
    def __init__(self, ra=None, dec=None, source='salt2-extended'):
        """
        Instantiate object

        Parameters
        ----------
        ra : float
            ra of the SN in degrees
        dec : float
            dec of the SN in degrees

        source : instance of `sncosmo.SALT2Source`, optional, defaults to using salt2-extended 
            source class to define the model
        """

        dust = sncosmo.OD94Dust()
        sncosmo.Model.__init__(self, source=source, effects=[dust, dust],
                               effect_names=['host', 'mw'],
                               effect_frames=['rest', 'obs'])

        # Current implementation of Model has a default value of mwebv = 0.
        # ie. no extinction, but this is not part of the API, so should not
        # depend on it, set explicitly in order to unextincted SED from
        # SNCosmo. We will use catsim extinction from `lsst.sims.photUtils`.

        self.ModelSource = source
        self.set(mwebv=0.)

        # self._ra, self._dec is initialized as None for cases where ra, dec
        # is not provided
        self._ra = None
        self._dec = None

        # ra, dec is input in degrees
        # If provided, set _ra, _dec in radians
        self._hascoords = True
        if dec is None:
            self._hascoords = False
        if ra is None:
            self._hascoords = False

        # Satisfied that coordinates provided are floats
        if self._hascoords:
            self.setCoords(ra, dec)

        # For values of ra, dec, the E(B-V) is calculated directly
        # from DustMaps
        self.lsstmwebv = EBVbase()
        self.ebvofMW = None
        if self._hascoords:
            self.mwEBVfromMaps()


        # Behavior of model outside temporal range :
        # if 'zero' then all fluxes outside the temporal range of the model
        # are set to 0.
        self._modelOutSideTemporalRange = 'zero'
        
        # SED will be rectified to 0. for negative values of SED if this
        # attribute is set to True
        self.rectifySED = True
        return
示例#12
0
class SNObject(sncosmo.Model):

    """
    Extension of the SNCosmo `TimeSeriesModel` to include more parameters and
    use methods in the catsim stack. We constrain ourselves to the use of a
    specific SALT model for the Supernova (Salt2-Extended), and set its MW
    extinction to be 0, since we will use the LSST software to calculate
    extinction.

    Parameters
    ----------
    ra : float
         ra of the SN in degrees
    dec : float
        dec of the SN in degrees


    Attributes
    ----------
    _ra : float or None
        ra of the SN in radians

    _dec : float or None
        dec of the SN in radians

    skycoord : `np.ndarray' of size 2 or None
        np.array([[ra], [dec]]), which are in radians

    ebvofMW : float or None
        mwebv value calculated from the self.skycoord if not None, or set to
        a value using self.set_MWebv. If neither of these are done, this value
        will be None, leading to exceptions in extinction calculation.
        Therefore, the value must be set explicitly to 0. to get unextincted
        quantities.
    rectifySED : Bool, True by Default
        if the SED is negative at the requested time and wavelength, return 0.
        instead of the negative value.


    Methods
    -------

    Examples
    --------
    >>> SNObject  = SNObject(ra=30., dec=60.)
    >>> SNObject._ra
    >>> 0.5235987755982988
    >>> SNObject._dec
    >>> 1.0471975511965976
    """

    def __init__(self, ra=None, dec=None, source='salt2-extended'):
        """
        Instantiate object

        Parameters
        ----------
        ra : float
            ra of the SN in degrees
        dec : float
            dec of the SN in degrees

        source : instance of `sncosmo.SALT2Source`, optional, defaults to using salt2-extended 
            source class to define the model
        """

        dust = sncosmo.OD94Dust()
        sncosmo.Model.__init__(self, source=source, effects=[dust, dust],
                               effect_names=['host', 'mw'],
                               effect_frames=['rest', 'obs'])

        # Current implementation of Model has a default value of mwebv = 0.
        # ie. no extinction, but this is not part of the API, so should not
        # depend on it, set explicitly in order to unextincted SED from
        # SNCosmo. We will use catsim extinction from `lsst.sims.photUtils`.

        self.ModelSource = source
        self.set(mwebv=0.)

        # self._ra, self._dec is initialized as None for cases where ra, dec
        # is not provided
        self._ra = None
        self._dec = None

        # ra, dec is input in degrees
        # If provided, set _ra, _dec in radians
        self._hascoords = True
        if dec is None:
            self._hascoords = False
        if ra is None:
            self._hascoords = False

        # Satisfied that coordinates provided are floats
        if self._hascoords:
            self.setCoords(ra, dec)

        # For values of ra, dec, the E(B-V) is calculated directly
        # from DustMaps
        self.lsstmwebv = EBVbase()
        self.ebvofMW = None
        if self._hascoords:
            self.mwEBVfromMaps()


        # Behavior of model outside temporal range :
        # if 'zero' then all fluxes outside the temporal range of the model
        # are set to 0.
        self._modelOutSideTemporalRange = 'zero'
        
        # SED will be rectified to 0. for negative values of SED if this
        # attribute is set to True
        self.rectifySED = True
        return

    @property
    def SNstate(self):
        """
        Dictionary summarizing the state of SNObject. Can be used to
        serialize to disk, and create SNObject from SNstate

        Returns : Dictionary with values of parameters of the model.
        """
        statedict = dict()

        # SNCosmo Parameters
        statedict['ModelSource'] = self.source.name
        for param_name in self.param_names:
            statedict[param_name] = self.get(param_name)

        # New Attributes
        # statedict['lsstmwebv'] = self.lsstmwebv
        statedict['_ra'] = self._ra
        statedict['_dec'] = self._dec
        statedict['MWE(B-V)'] = self.ebvofMW

        return statedict

    @classmethod
    def fromSNState(cls, snState):
        """
        creates an instance of SNObject with a state described by snstate.

        Parameters
        ----------
        snState: Dictionary summarizing the state of SNObject

        Returns
        -------
        Instance of SNObject class with attributes set by snstate

        Example
        -------

        """
        # Separate into SNCosmo parameters and SNObject parameters
        dust = sncosmo.OD94Dust()
        sncosmoModel = sncosmo.Model(source=snState['ModelSource'],
                                     effects=[dust, dust],
                                     effect_names=['host', 'mw'],
                                     effect_frames=['rest', 'obs'])

        sncosmoParams = cls.sncosmoParamDict(snState, sncosmoModel)

        # Now create the class
        cls = SNObject(source=snState['ModelSource'])

        # Set the SNObject coordinate properties
        # Have to be careful to not convert `None` type objects to degrees
        setdec, setra = False, False
        if snState['_ra'] is not None:
            ra = np.degrees(snState['_ra'])
            setra = True
        if snState['_dec'] is not None:
            dec = np.degrees(snState['_dec'])
            setdec = True
        if setdec and setra:
            cls.setCoords(ra, dec)

        # Set the SNcosmo parameters
        cls.set(**sncosmoParams)

        # Set the ebvofMW by hand
        cls.ebvofMW = snState['MWE(B-V)']

        return cls

    @property
    def modelOutSideTemporalRange(self):
        """
        Defines the behavior of the model when sampled at times beyond the model
        definition.
        """
        return self._modelOutSideTemporalRange

    @modelOutSideTemporalRange.setter
    def modelOutSideTemporalRange(self, value):
        if value != 'zero':
            raise ValueError('Model not implemented, defaulting to zero method\n')
        return self._modelOutSideTemporalRange


    def equivalentSNCosmoModel(self):
        """
        returns an SNCosmo Model which is equivalent to SNObject
        """
        snState = self.SNstate
        dust = sncosmo.OD94Dust()
        sncosmoModel = sncosmo.Model(source=snState['ModelSource'],
                                     effects=[dust, dust],
                                     effect_names=['host', 'mw'],
                                     effect_frames=['rest', 'obs'])

        sncosmoParams = self.sncosmoParamDict(snState, sncosmoModel)
        sncosmoParams['mwebv'] = snState['MWE(B-V)']
        sncosmoModel.set(**sncosmoParams)
        return sncosmoModel


    @staticmethod
    def equivsncosmoParamDict(SNstate, SNCosmoModel):
        """
        return a dictionary that contains the parameters of SNCosmoModel
        that are contained in SNstate

        Parameters
        ----------
        SNstate : `SNObject.SNstate`, mandatory
            Dictionary defining the state of a SNObject
        SNCosmoModel : A `sncosmo.Model` instance, mandatory

        Returns
        -------
        sncosmoParams: Dictionary of sncosmo parameters

        """
        sncosmoParams = dict()
        for param in SNstate.keys():
            if param in SNCosmoModel.param_names:
                sncosmoParams[param] = SNstate[param]
        sncosmoParams['mwebv'] = SNstate['MWE(B-V)']
        return sncosmoParams

    @staticmethod
    def sncosmoParamDict(SNstate, SNCosmoModel):
        """
        return a dictionary that contains the parameters of SNCosmoModel
        that are contained in SNstate. Note that this does not return the
        equivalent SNCosmo  model.

        Parameters
        ----------
        SNstate : `SNObject.SNstate`, mandatory
            Dictionary defining the state of a SNObject
        SNCosmoModel : A `sncosmo.Model` instance, mandatory

        Returns
        -------
        sncosmoParams: Dictionary of sncosmo parameters

        """
        sncosmoParams = dict()
        for param in SNstate.keys():
            if param in SNCosmoModel.param_names:
                sncosmoParams[param] = SNstate[param]
        return sncosmoParams



    def summary(self):
        '''
        summarizes the current state of the SNObject class in a returned
        string.

        Parameters
        ----------
        None

        Returns
        -------
        Summary State in string format

        Examples
        --------
        >>> t = SNObject()
        >>> print t.summary()
        '''
        state = '  SNObject Summary      \n'

        state += 'Model = ' + '\n'
        state += 'z = ' + str(self.get('z')) + '\n'
        state += 'c = ' + str(self.get('c')) + '\n'
        state += 'x1 = ' + str(self.get('x1')) + '\n'
        state += 'x0 = ' + str(self.get('x0')) + '\n'
        state += 't0 = ' + str(self.get('t0')) + '\n'
        state += 'ra = ' + str(self._ra) + ' in radians \n'
        state += 'dec = ' + str(self._dec) + ' in radians \n'
        state += 'MW E(B-V) = ' + str(self.ebvofMW) + '\n'

        return state

    def setCoords(self, ra, dec):
        """
        set the ra and dec coordinate of SNObject to values in radians
        corresponding to the given values in degrees

        Parameters
        ----------
        ra: float, mandatory
            the ra in degrees
        dec: float, mandatory
            dec in degrees

        Returns
        -------
        None

        Examples
        --------
        >>> t = SNObject()
        >>> t.setCoords(ra=30., dec=90.)
        >>> t._ra
        >>> 0.5235987755982988
        >>> t._dec
        >>> 1.0471975511965976
        """

        if ra is None or dec is None:
            raise ValueError('Why try to set coordinates without full'
                             'coordiantes?\n')
        self._ra = np.radians(ra)
        self._dec = np.radians(dec)
        self.skycoord = np.array([[self._ra], [self._dec]])

        self._hascoords = True

        return

    def set_MWebv(self, value):
        """
        if mwebv value is known, this can be used to set the attribute
        ebvofMW of the SNObject class to the value (float).

        Parameters
        ----------
        value: float, mandatory
               value of mw extinction parameter E(B-V) in mags to be used in
               applying extinction to the SNObject spectrum

        Returns
        -------
        None

        Examples
        --------
        >>> t = SNObject()
        >>> t.set_MWebv(0.)
        >>> 0.
        """
        self.ebvofMW = value
        return

    def mwEBVfromMaps(self):
        """
        set the attribute ebvofMW of the class from the ra and dec
        of the SN. If the ra or dec attribute of the class is None,
        set this attribute to None.

        Parameters
        ----------
        None

        Returns
        -------
        None

        Examples
        --------
        >>> t = SNObject()
        >>> t.setCoords(ra=30., dec=60.)
        >>> t.mwEBVfromMaps()
        >>> t.ebvofMW
        >>> 0.977767825127

        .. note:: This function must be run after the class has attributes ra
                  and dec set. In case it is run before this, the mwebv value
                  will be set to None.

        """

        if not self._hascoords:
            raise ValueError('Cannot Calculate EBV from dust maps if ra or dec'
                             'is `None`')
        self.ebvofMW = self.lsstmwebv.calculateEbv(
            equatorialCoordinates=self.skycoord)[0]
        return


    def redshift(self, z, cosmo):
        """
        Redshift the instance holding the intrinsic brightness of the object
        fixed. By intrinsic brightness here, we mean the BessellB band asbolute
        magnitude in rest frame. This requires knowing the cosmology


        Parameters
        ----------
        z : float, mandatory
            redshift at which the object must be placed.
        cosmo : instance of `astropy.cosmology` objects, mandatory
            specifies the cosmology.
        Returns
        -------
        None, but it changes the instance

        """
        import numbers

        # Check that the input redshift is a scalar
        try:
            assert isinstance(z, numbers.Number)
        except:
            raise TypeError('The argument z in method redshift should be'
                            'a scalar Numeric')

        # Ensure that the input redshift is greater than 0.
        try:
            assert z > 0.
        except:
            raise ValueError('The argument z in the method SNObject.redshift'
                             'should be greater than 0.')

        # Find the current value of the rest frame BessellB AB magnitude
        peakAbsMag = self.source_peakabsmag('BessellB', 'AB', cosmo=cosmo)
        self.set(z=z)
        self.set_source_peakabsmag(peakAbsMag, 'BessellB', 'AB', cosmo=cosmo)
        return

    def SNObjectSED(self, time, wavelen=None, bandpass=None,
                    applyExtinction=True):
        '''
        return a `lsst.sims.photUtils.sed` object from the SN model at the
        requested time and wavelengths with or without extinction from MW
        according to the SED extinction methods. The wavelengths may be
        obtained from a `lsst.sims.Bandpass` object or a `lsst.sims.BandpassDict`
        object instead. (Currently, these have the same wavelengths). See notes
        for details on handling of exceptions.

        If the sed is requested at times outside the validity range of the
        model, the flux density is returned as 0. If the time is within the
        range of validity of the model, but the wavelength range requested
        is outside the range, then the returned fluxes are np.nan outside
        the range, and the model fluxes inside

        Parameters
        ----------
        time: float
            time of observation
        wavelen: `np.ndarray` of floats, optional, defaults to None
            array containing wavelengths in nm
        bandpass: `lsst.sims.photUtils.Bandpass` object or
            `lsst.sims.photUtils.BandpassDict`, optional, defaults to `None`.
            Using the dict assumes that the wavelength sampling and range
            is the same for all elements of the dict.

            if provided, overrides wavelen input and the SED is
            obtained at the wavelength values native to bandpass
            object.


        Returns
        -------
        `sims_photutils.sed` object containing the wavelengths and SED
        values from the SN at time time in units of ergs/cm^2/sec/nm


        .. note: If both wavelen and bandpassobject are `None` then exception,
                 will be raised.
        Examples
        --------
        >>> sed = SN.SNObjectSED(time=0., wavelen=wavenm)
        '''

        if wavelen is None and bandpass is None:
            raise ValueError('A non None input to either wavelen or\
                              bandpassobject must be provided')

        # if bandpassobject present, it overrides wavelen
        if bandpass is not None:
            if isinstance(bandpass, BandpassDict):
                firstfilter = bandpass.keys()[0]
                bp = bandpass[firstfilter]
            else:
                bp = bandpass
            # remember this is in nm
            wavelen = bp.wavelen

        flambda = np.zeros(len(wavelen))


        # self.mintime() and self.maxtime() are properties describing
        # the ranges of SNCosmo.Model in time. Behavior beyond this is 
        # determined by self.modelOutSideTemporalRange
        if (time >= self.mintime()) and (time <= self.maxtime()):
            # If SNCosmo is requested a SED value beyond the wavelength range
            # of model it will crash. Try to prevent that by returning np.nan for
            # such wavelengths. This will still not help band flux calculations
            # but helps us get past this stage.

            flambda = flambda * np.nan

            # Convert to Ang
            wave = wavelen * 10.0
            mask1 = wave >= self.minwave()
            mask2 = wave <= self.maxwave()
            mask = mask1 & mask2
            wave = wave[mask]

            # flux density dE/dlambda returned from SNCosmo in
            # ergs/cm^2/sec/Ang, convert to ergs/cm^2/sec/nm

            flambda[mask] = self.flux(time=time, wave=wave)
            flambda[mask] = flambda[mask] * 10.0
        else:
            # use prescription for modelOutSideTemporalRange
            if self.modelOutSideTemporalRange != 'zero':
                raise NotImplementedError('Model not implemented, change to zero\n')
                # Else Do nothing as flambda is already 0.
                # This takes precedence over being outside wavelength range
                
        if self.rectifySED:
            # Note that this converts nans into 0.
            flambda = np.where(flambda > 0., flambda, 0.)
        SEDfromSNcosmo = Sed(wavelen=wavelen, flambda=flambda)

        if not applyExtinction:
            return SEDfromSNcosmo

        # Apply LSST extinction
        global _sn_ax_cache
        global _sn_bx_cache
        global _sn_ax_bx_wavelen
        if _sn_ax_bx_wavelen is None \
        or len(wavelen)!=len(_sn_ax_bx_wavelen) \
        or (wavelen!=_sn_ax_bx_wavelen).any():

            ax, bx = SEDfromSNcosmo.setupCCMab()
            _sn_ax_cache = ax
            _sn_bx_cache = bx
            _sn_ax_bx_wavelen = np.copy(wavelen)
        else:
            ax = _sn_ax_cache
            bx = _sn_bx_cache

        if self.ebvofMW is None:
            raise ValueError('ebvofMW attribute cannot be None Type and must'
                             ' be set by hand using set_MWebv before this'
                             'stage, or by using setcoords followed by'
                             'mwEBVfromMaps\n')

        SEDfromSNcosmo.addCCMDust(a_x=ax, b_x=bx, ebv=self.ebvofMW)
        return SEDfromSNcosmo

    def SNObjectSourceSED(self, time, wavelen=None):
        """
        Return the rest Frame SED of SNObject at the phase corresponding to
        time, at rest frame wavelengths wavelen. If wavelen is None,
        then the SED is sampled at the rest frame wavelengths native to the
        SALT model being used.

        Parameters
        ----------
        time : float, mandatory,
            observer frame time at which the SED has been requested in units
            of days.
        wavelen : `np.ndarray`, optional, defaults to native SALT wavelengths
            array of wavelengths in the rest frame of the supernova in units
            of nm. If None, this defaults to the wavelengths at which the
            SALT model is sampled natively.
        Returns
        -------
        `numpy.ndarray` of dtype float.

        .. note: The result should usually match the SALT source spectrum.
        However, it may be different for the following reasons:
        1. If the time of observation is outside the model range, the values
            have to be inserted using additional models. Here only one model
            is currently implemented, where outside the model range the value
            is set to 0.
        2. If the wavelengths are beyond the range of the SALT model, the SED
            flambda values are set to `np.nan` and these are actually set to 0.
            if `self.rectifySED = True`
        3. If the `flambda` values of the SALT model are negative which happens
            in the less sampled phases of the model, these values are set to 0,
            if `self.rectifySED` = True.
        """
        phase = (time - self.get('t0')) / (1. + self.get('z'))
        source = self.source

        # Set the default value of wavelength  input
        if wavelen is None:
            # use native SALT grid in Ang
            wavelen = source._wave
        else:
            #input wavelen in nm, convert to Ang
            wavelen = wavelen.copy()
            wavelen *= 10.0

        flambda = np.zeros(len(wavelen))
        # self.mintime() and self.maxtime() are properties describing
        # the ranges of SNCosmo.Model in time. Behavior beyond this is 
        # determined by self.modelOutSideTemporalRange
        insidephaseRange = (phase <= source.maxphase())and(phase >= source.minphase())
        if insidephaseRange:
            # If SNCosmo is requested a SED value beyond the wavelength range
            # of model it will crash. Try to prevent that by returning np.nan for
            # such wavelengths. This will still not help band flux calculations
            # but helps us get past this stage.

            flambda = flambda * np.nan

            mask1 = wavelen >= source.minwave()
            mask2 = wavelen <= source.maxwave()
            mask = mask1 & mask2
            # Where we have to calculate fluxes because it is not `np.nan`
            wave = wavelen[mask]
            flambda[mask] = source.flux(phase, wave)
        else:
            if self.modelOutSideTemporalRange == 'zero':
                # flambda was initialized as np.zeros before start of
                # conditional
                pass
            else:
                raise NotImplementedError('Only modelOutSideTemporalRange=="zero" implemented')


        # rectify the flux
        if self.rectifySED:
            flux = np.where(flambda>0., flambda, 0.)
        else:
            flux = flambda


        # convert per Ang to per nm
        flux *= 10.0
        # convert ang to nm
        wavelen = wavelen / 10.
        sed = Sed(wavelen=wavelen, flambda=flux)
        # This has the cosmology built in.
        return sed

    def catsimBandFlux(self, time, bandpassobject):
        """
        return the flux in the bandpass in units of maggies which is the flux
        the AB magnitude reference spectrum would have in the same band.

        Parameters
        ----------
        time: mandatory, float
            MJD at which band fluxes are evaluated
        bandpassobject: mandatory, `lsst.sims.photUtils.BandPass` object
            A particular bandpass which is an instantiation of one of
            (u, g, r, i, z, y)
        Returns
        -------
        float value for flux in band in units of maggies

        Examples
        --------
        >>> bandpassnames = ['u', 'g', 'r', 'i', 'z', 'y']
        >>> LSST_BandPass = BandpassDict.loadTotalBandpassesFromFiles()
        >>> SN = SNObject(ra=30., dec=-60.)
        >>> SN.set(z=0.96, t0=571181, x1=2.66, c=0.353, x0=1.796112e-06)
        >>> SN.catsimBandFlux(bandpassobject=LSST_BandPass['r'], time=571190.)
        >>> 1.9856857972304903e-11

        .. note: If there is an unphysical value of sed in
        the wavelength range, it produces a flux of  `np.nan`
        """
        # Speedup for cases outside temporal range of model
        if time <= self.mintime() or time >= self.maxtime() :
            return 0.
        SEDfromSNcosmo = self.SNObjectSED(time=time,
                                          bandpass=bandpassobject)
        return SEDfromSNcosmo.calcFlux(bandpass=bandpassobject) / 3631.0
 
    def catsimBandMag(self, bandpassobject, time, fluxinMaggies=None,
                      noNan=False):
        """
        return the magnitude in the bandpass in the AB magnitude system

        Parameters
        ----------
        bandpassobject : mandatory,`sims.photUtils.BandPass` instances
            LSST Catsim bandpass instance for a particular bandpass
        time : mandatory, float
            MJD at which this is evaluated
        fluxinMaggies: float, defaults to None
            provide the flux in maggies, if not provided, this will be evaluated
        noNan : Bool, defaults to False
            If True, an AB magnitude of 200.0 rather than nan values is
            associated with a flux of 0.
        Returns
        -------
        float value of band magnitude in AB system

        Examples
        --------
        """
        if fluxinMaggies is None:
            fluxinMaggies = self.catsimBandFlux(bandpassobject=bandpassobject,
                                                time=time)
        if noNan:
            if fluxinMaggies <= 0.:
                return 200.0
        return -2.5 * np.log10(fluxinMaggies)

    def catsimBandFluxError(self, time, bandpassobject, m5,
                            fluxinMaggies=None,
                            magnitude=None,
                            photParams=None):
        """
        return the flux uncertainty in the bandpass in units 'maggies'
        (the flux the AB magnitude reference spectrum would have in the
        same band.) for a source of given brightness. The source brightness
        may be calculated, but the need for calculation is overridden by a
        provided flux in bandpass (in units of maggies) which itself may be
        overridden by a provided magnitude. If the provided/calculated flux
        is 0. or negative the magnitude calculated is taken to be 200.0 rather
        than a np.nan.


        Parameters
        ----------
        time: mandatory, float
            MJD at which band fluxes are evaluated
        bandpassobject: mandatory, `lsst.sims.photUtils.BandPass` object
            A particular bandpass which is an instantiation of one of
            (u, g, r, i, z, y)
        m5 : float, mandatory
            fiveSigma Depth for the sky observation
        photParams : instance of `sims.photUtils.PhotometricParameters`, defaults to `None` 
            describes the hardware parameters of the Observing system
        magnitude : float, defaults to None
            AB magnitude of source in bandpass.
        fluxinMaggies : float, defaults to None
            flux in Maggies for source in bandpass
        Returns
        -------
        float

        Examples
        --------
        .. note: If there is an unphysical value of sed the fluxinMaggies might
        be `np.nan`. The magnitude calculated from this is calculated using `noNan`
         and is therefore 200.0 rather than `np.nan`. 
        """
        if fluxinMaggies is None:
            fluxinMaggies = self.catsimBandFlux(time=time,
                                                bandpassobject=bandpassobject)
        if magnitude is None:
            mag = self.catsimBandMag(time=time, fluxinMaggies=fluxinMaggies,
                                     bandpassobject=bandpassobject, noNan=True)
        else:
            mag = magnitude

        # recalculate fluxinMaggies as the previous one might have been `np.nan`
        # the noise is contaminated if this is `np.nan`
        fluxinMaggies = 10.0**(-0.4 * mag)

        if photParams is None:
            photParams = PhotometricParameters()

        SNR, gamma = calcSNR_m5(magnitude=mag, bandpass=bandpassobject,
                                m5=m5, photParams=photParams)
        return fluxinMaggies / SNR

    def catsimBandMagError(self, time, bandpassobject, m5, photParams=None,
                           magnitude=None):
        """
        return the 68 percent uncertainty on the magnitude in the bandpass

        Parameters
        ----------
        time: mandatory, float
            MJD at which band fluxes are evaluated
        bandpassobject: mandatory, `lsst.sims.photUtils.BandPass` object
            A particular bandpass which is an instantiation of one of
            (u, g, r, i, z, y)
        m5 :
        photParams :
        magnitude :

        Returns
        -------
        float

        Examples
        --------
        .. note: If there is an unphysical value of sed in
        the wavelength range, it produces a flux of  `np.nan`
        """

        if magnitude is None:
            mag = self.catsimBandMag(time=time,
                                     bandpassobject=bandpassobject,
                                     noNan=True)
        else:
            mag = magnitude

        bandpass = bandpassobject

        if photParams is None:
            photParams = PhotometricParameters()

        magerr = calcMagError_m5(magnitude=mag,
                                 bandpass=bandpassobject,
                                 m5=m5,
                                 photParams=photParams)
        return magerr[0]


    def catsimManyBandFluxes(self, time, bandpassDict,
                             observedBandPassInd=None):
        """
        return the flux in the multiple bandpasses of a bandpassDict
        indicated by observedBandPassInd in units of maggies

        Parameters
        ----------
        time: mandatory, float
            MJD at which band fluxes are evaluated
        bandpassDict: mandatory, `lsst.sims.photUtils.BandpassDict` instance
        observedBandPassInd : optional, list of integers, defaults to None
            integer correspdonding to index of the bandpasses used in the
            observation in the ordered dict bandpassDict
        Returns
        -------
        `~numpy.ndarray` of length =len(observedBandPassInd)

        Examples
        --------
        .. note: If there is an unphysical value of sed in
        the wavelength range, it produces a flux of  `np.nan`
        """
        SEDfromSNcosmo = self.SNObjectSED(time=time,
                                          bandpass=bandpassDict['u'])
        wavelen_step = np.diff(SEDfromSNcosmo.wavelen)[0]
        SEDfromSNcosmo.flambdaTofnu()
        f = SEDfromSNcosmo.manyFluxCalc(bandpassDict.phiArray,
                                        wavelen_step=wavelen_step,
                                        observedBandpassInd=observedBandPassInd)
        return f / 3631.

    def catsimManyBandMags(self, time, bandpassDict,
                           observedBandPassInd=None):
        """
        return the flux in the bandpass in units of the flux
        the AB magnitude reference spectrum would have in the
        same band.

        Parameters
        ----------
        time: mandatory, float
            MJD at which band fluxes are evaluated
        bandpassDict: mandatory, `lsst.sims.photUtils.BandpassDict` instance
        observedBandPassInd : optional, list of integers, defaults to None
            integer correspdonding to index of the bandpasses used in the
            observation in the ordered dict bandpassDict
        Returns
        -------
        `~numpy.ndarray` of length =len(observedBandPassInd)

        Examples
        --------
        .. note: If there is an unphysical value of sed in
        the wavelength range, it produces a flux of  `np.nan`
        """
        f = self.catsimManyBandFluxes(time,
                                      bandpassDict,
                                      observedBandPassInd)

        return -2.5 * np.log10(f)


    def catsimManyBandADUs(self, time, bandpassDict,
                  photParams=None,
                  observedBandPassInds=None):
        """
        time: float, mandatory
            MJD of the observation

        bandpassDict: mandatory,
            Dictionary of instances of `sims.photUtils.Bandpass` for
            filters

        photParams: Instance of `sims.photUtils.PhotometricParameters`, optional,
                    defaults to None
                    Describes the observational parameters used in specifying the
                    photometry of the ovservation
        observedBandPassInd: None
            Not used now
        """
        SEDfromSNcosmo = self.SNObjectSED(time=time,
                                          bandpass=bandpassDict)

        bandpassNames = list(bandpassDict.keys())
        adus = np.zeros(len(bandpassNames))

        for i, filt in enumerate(bandpassNames):
            bandpass = bandpassDict[filt]
            adus[i] = SEDfromSNcosmo.calcADU(bandpass, photParams=photParams)

        return adus
示例#13
0
                        if pass_event:

                            dust = sncosmo.OD94Dust()
                            SN = sncosmo.Model(source='salt2-extended',
                                               effects=[dust, dust],
                                               effect_names=['host', 'mw'],
                                               effect_frames=['rest', 'obs'])
                            SN.set(z=obj['z'])
                            SN.set(t0=obj['t0'])
                            SN.set(c=obj['c'])
                            SN.set(x1=obj['x1'])
                            SN.set_source_peakabsmag(-19.3,
                                                     'bessellB',
                                                     'vega',
                                                     cosmo=cosmology.WMAP9)
                            lsstmwebv = EBVbase()
                            ebvofMW = lsstmwebv.calculateEbv(
                                equatorialCoordinates=np.array(
                                    [[obj['ra']], [obj['dec']]]))[0]
                            print 'hello', obj['ra'], obj['dec'], ebvofMW
                            SN.set(mwebv=ebvofMW)
                            print 'simulated', obj['z'], obj['t0'], obj[
                                'c'], obj['x1']
                            resb, fitted_modelb = sncosmo.fit_lc(
                                dict_tag['table_for_fit'],
                                SN, ['z', 't0', 'x0', 'x1', 'c'],
                                bounds={
                                    'z': (obj['z'] - 0.01, obj['z'] + 0.01)
                                })
                            sncosmo.plot_lc(dict_tag['table_for_fit'],
                                            model=fitted_modelb,