Esempio n. 1
0
def get_transient_model(model_type='built-in', **kwargs):
    """
    """
    model = _transient_loaders[model_type](**kwargs)

    if kwargs.get('host_extinction', False):
        model.add_effect(sncosmo.CCM89Dust(), 'host', 'rest')
        model.set(hostr_v=2.)
    model.add_effect(sncosmo.CCM89Dust(), 'mw', 'obs')

    return model
Esempio n. 2
0
    def __init__(self,
                 metricName='ctmetric_lsst',
                 magPrecision=0.01,
                 limitingsnr=5.,
                 uniqueBlocks=False,
                 **kwargs):
        """
            """
        cols = ['expMJD', 'filter', 'fiveSigmaDepth']  #,'fieldRA','fieldDec']

        super(ctmetric_lsst, self).__init__(cols, metricName)

        self.metriccache = dict()
        self.ebvprecision = 0.01
        self.limitingsnr = limitingsnr

        self.ccm = sncosmo.CCM89Dust()

        self.metricDtype = 'float'

        #survey args
        self.filterinfo = lsst_info.LSST.filterinfo

        #metric args
        self.magPrecision = magPrecision

        self.map = lsst.sims.photUtils.EBV.EbvMap()

        dotlocation = string.rfind(kwargs['lc.class'], '.')
        module_name = kwargs['lc.class'][0:dotlocation]
        class_name = kwargs['lc.class'][dotlocation + 1:]
        somemodule = importlib.import_module(module_name)

        self.lightcurve = getattr(somemodule, class_name)(**kwargs)
Esempio n. 3
0
    def setUp(self) -> None:
        self.model = SNModel(source=sncosmo_test_models.flatsource(),
                             effects=[sncosmo.CCM89Dust()],
                             effect_frames=['obs'],
                             effect_names=['mw'])

        self.model.set(z=0.0001)
Esempio n. 4
0
    def fitting_z(self, sn_name):
        """SALT2 fit using SNCOSMO for the SN without => z free parameter of the
        fit
        """
        self.read(sn_name)
        self.source = sncosmo.get_source('salt2', version='2.4')
        dust = sncosmo.CCM89Dust()
        self.model = sncosmo.Model(source=self.source,
                                   effects=[dust],
                                   effect_names=['mw'],
                                   effect_frames=['obs'])
        self.model.set(mwebv=self.mwebv)
        #self.model.set(c=0)

        try:
            results, fit_model = sncosmo.fit_lc(self.data, self.model,
                                                ['t0', 'x1', 'c', 'x0'])
            #res, fitted_model = sncosmo.fit_lc(self.data, self.model, ['t0','x1', 'x0'])
            #return res, fitted_model
        except:
            #except RuntimeError:
            print('Fail:', sn_name)
            results, fit_model = 'fit fail', np.nan

        return results, fit_model
Esempio n. 5
0
    def extinction(self, eb_v, dust_law, r_v=3.1):
        """ Given eb-v and r-v return the dust extinction in a particular BAND 
         It can use:
         Cardelli dust law (CCM),
         ODonneal (OD94)
         Fitzpatrick (F99)
        
        KEEP IN MIND:
        _minwave = 909.09
        _maxwave = 33333.33
         """
        if dust_law == 'OD94':
            dust = sncosmo.OD94Dust()
        elif dust_law == 'CCM':
            dust = sncosmo.CCM89Dust()
        elif dust_law == 'F99':
            dust = sncosmo.F99Dust()
        else:
            print('Add this dust law! I dont know it')

        dust.parameters = [eb_v, r_v]
        w = self.wave
        t = self.transmission
        ext = dust.propagate(w, t)
        correction_extinction = np.trapz((ext)[1:-1], w[1:-1]) / np.trapz(
            (t)[1:-1], w[1:-1])
        return correction_extinction
Esempio n. 6
0
    def fitting(self, sn_name):
        """Fit the light curve for a SN (data as Astropy table) using the model
        SALT2 z and mwebv are setted, it returns the values of the SALT2 parameters
        and their errors. We plot the fit on the notebook.
        """
        self.read(sn_name)
        self.source = sncosmo.get_source('salt2', version='2.4')
        dust = sncosmo.CCM89Dust()
        self.model = sncosmo.Model(source=self.source,
                                   effects=[dust],
                                   effect_names=['mw'],
                                   effect_frames=['obs'])
        self.model.set(mwebv=self.mwebv)
        self.model.set(z=self.zhl)
        #self.model.set(c=0)

        try:
            res, fitted_model = sncosmo.fit_lc(self.data,
                                               self.model,
                                               ['t0', 'x1', 'c', 'x0'],
                                               phase_range=(-15, 45))
            #res, fitted_model = sncosmo.fit_lc(self.data, self.model, ['t0','x1', 'x0'])
            #return res, fitted_model
        except:
            #except RuntimeError:
            print('Fail:', sn_name)
            res, fitted_model = 'fit fail', np.nan

        return res, fitted_model
Esempio n. 7
0
    def test_error_for_bad_frame(self) -> None:
        """Test an error is raised for a band reference frame name"""

        model = SNModel(source='salt2')
        with self.assertRaises(ValueError):
            model.add_effect(effect=sncosmo.CCM89Dust(),
                             frame='bad_frame_name',
                             name='mw')
Esempio n. 8
0
    def test_free_effect_adds_z_parameter(self) -> None:
        """Test effects in the ``free`` frame of reference include an added redshift parameter"""

        effect_name = 'freeMW'
        model = SNModel(source='salt2')
        model.add_effect(effect=sncosmo.CCM89Dust(),
                         frame='free',
                         name=effect_name)
        self.assertIn(effect_name + 'z', model.param_names)
Esempio n. 9
0
    def setUp(self) -> None:
        # Same as the base sncosmo setup procedure, but using a ``SNModel``
        # instance instead of ``sncosmo.Model``
        self.model = SNModel(source=sncosmo_test_models.flatsource(),
                             effects=[sncosmo.CCM89Dust()],
                             effect_frames=['obs'],
                             effect_names=['mw'])

        self.model.set(z=0.0001)
def model_(phase=0, wave=0, cos_theta=0, flux=0, viewingangle_dependece=True):
    '''phase, wave, cos_theta and flux are 1D arrays with the same length'''
    if viewingangle_dependece:
        source = AngularTimeSeriesSource(phase, wave, cos_theta, flux)
    else:
        source = sncosmo.TimeSeriesSource(phase, wave, flux)
    dust = sncosmo.CCM89Dust()
    return sncosmo.Model(source=source,
                         effects=[dust, dust],
                         effect_names=['host', 'MW'],
                         effect_frames=['rest', 'obs'])
Esempio n. 11
0
def create_SALT2_model(ts_data, meta_data, object_id_list):
    warnings.simplefilter("ignore")

    result_list = []
    for object_id in object_id_list:
        if object_id is None:
            # for itertools.zip_longest method
            continue

        result_tmp = [object_id]
        photoz = meta_data.query(
            'object_id == @object_id')["hostgal_photoz"].values[0]
        mwebv = meta_data.query('object_id == @object_id')["mwebv"].values[0]

        if photoz == 0:
            result_tmp.extend([np.nan, np.nan, np.nan, np.nan])
            result_list.append(result_tmp)
            continue

        extract_obj = ts_data.query('object_id == @object_id')
        data = astropy.table.Table(
            extract_obj.values,
            names=['object_id', 'mjd', 'band', 'flux', 'flux_err', 'detected'],
            dtype=('str', 'float', 'str', 'float', 'float', 'str'))

        # model = sncosmo.Model(source='salt2')
        dust = sncosmo.CCM89Dust()
        model = sncosmo.Model(source='salt2-extended',
                              effects=[dust, dust],
                              effect_names=['host', 'mw'],
                              effect_frames=['rest', 'obs'])
        model.set(z=photoz, mwebv=mwebv, hostebv=0, hostr_v=3.1, mwr_v=3.1)

        # cutting data
        data_mask = model.bandoverlap(data["band"], z=photoz)
        data = data[data_mask]

        def objective(parameters):
            model.parameters[1:5] = parameters
            model_flux = model.bandflux(data['band'], data['mjd'])
            return np.sum(((data['flux'] - model_flux) / data['flux_err'])**2)

        start_parameters = [60000, 1e-5, 0., 0.]  # t0, x0, x1, c
        bounds = [(extract_obj.mjd.min(), extract_obj.mjd.max()), (None, None),
                  (None, None), (None, None)]
        parameters, val, info = fmin_l_bfgs_b(objective,
                                              start_parameters,
                                              bounds=bounds,
                                              approx_grad=True)
        result_tmp.extend(parameters)

        result_list.append(result_tmp)

    return result_list
Esempio n. 12
0
    def set_model(self, model):
        """
        Set the transient model.
        If it does not have MW dust effect, the effect is added.
        """
        if model.__class__ is not sncosmo.models.Model:
            raise TypeError("model must be sncosmo.model.Model")

        if "mwebv" not in model.param_names:
            model.add_effect(sncosmo.CCM89Dust(), 'mw', 'obs')

        self._properties["model"] = model
Esempio n. 13
0
def calc_mb(**param_dict):
    """Calculates the apparent magnitude in the B-band based on the 
    SALT2 parameters in the param_dict"""
    model = sncosmo.Model(source='salt2',
                          effects=[sncosmo.CCM89Dust()],
                          effect_names=['mw'],
                          effect_frames=['obs'])
    model.set(**param_dict)
    try:
        mb = model.bandmag(band='bessellb', time=param_dict['t0'], magsys='ab')
    except:
        mb = np.nan
    return mb
Esempio n. 14
0
    def __init__(self,
                 metricName='snmetric_lsst',
                 filterNames=numpy.array(['u', 'g', 'r', 'i', 'z', 'y']),
                 filterTargetMag=numpy.array([22, 22.5, 22.5, 22.5, 22.5, 22]),
                 filterWave=numpy.array([375., 476., 621., 754., 870., 980.]),
                 T0=30.,
                 Omega=1.,
                 zmax=.5,
                 snr=50.,
                 tau=4.,
                 dt0=28.,
                 a=1.,
                 uniqueBlocks=False,
                 **kwargs):
        """
            """

        cols = ['night', 'filter', 'fivesigma_modified', 'fieldRA', 'fieldDec']
        super(snmetric_lsst, self).__init__(cols, metricName, **kwargs)

        self.longestTolerableGap = 15.

        self.metricDtype = 'float'
        #survey args
        self.filterinfo = dict()
        for name, mag, wave in zip(filterNames, filterTargetMag, filterWave):
            self.filterinfo[name] = dict()
            self.filterinfo[name]['targetMag'] = mag
            self.filterinfo[name]['wave'] = wave

        #self.filterNames = filterNames
        #self.filterTargetMag = filterTargetMag
        #self.filterWave=filterWave

        #metric args
        # for now these are all scalars though in principle could be filter-dependent
        self.T0 = T0
        self.Omega = Omega
        self.zmax = zmax
        self.snr = snr
        self.tau = tau
        self.dt0 = dt0
        self.a = a

        self.ccm = sncosmo.CCM89Dust()
        self.map = lsst.sims.photUtils.EBV.EbvMap()
        self.metric_calc = surveymetrics.snmetric.Metric.OneFieldBandMetric(
            self.Omega, self.zmax, self.snr, self.T0, self.tau, self.dt0,
            self.a)
Esempio n. 15
0
def test_bandpass_type():
    """Check that bandpass wavelength type is always float64,
    and that color laws work with them."""

    dust = sncosmo.CCM89Dust()

    for dt in [np.int32, np.int64, np.float32]:
        wave = np.arange(4000., 5000., 20., dtype=dt)
        trans = np.ones_like(wave)
        band = sncosmo.Bandpass(wave, trans)

        assert band.wave.dtype == np.float64

        # Ensure that it works with cython-based propagation effect.
        dust.propagate(band.wave, np.ones_like(wave))
Esempio n. 16
0
    def equivalentSNCosmoModel(self):
        """
        returns an SNCosmo Model which is equivalent to SNObject
        """
        snState = self.SNstate
        dust = sncosmo.CCM89Dust()
        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
Esempio n. 17
0
    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.CCM89Dust()
        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
Esempio n. 18
0
def lens_extinction(source='salt2-extended',
                    zs=1.95,
                    zl=0.338,
                    Av=1,
                    dust=sncosmo.CCM89Dust(),
                    t=0):
    # the source makes no difference, dust has same effect on every model
    # the model as it would look like for obs at the lens plane w no dust
    model = sncosmo.Model(source=source)
    model.set(z=zs - zl)
    # the model as it would look for obs at lens w dust
    dust_model = sncosmo.Model(source=source,
                               effects=[dust],
                               effect_names=['mw'],
                               effect_frames=['obs'])
    dust_model.set(z=zs - zl)
    r_v = 3.1  # AV/E(B-V) typical value for diffuse ISM
    ebv = Av / r_v
    dust_model.set(mwebv=ebv, mwr_v=r_v)
    """
    I want to know how the dust dimmed f160w & f105w in our frame ie zl~0.338 further
    f160w ~ 16000 & f105w ~ 10500 (Angstrom), they have widths about 1500 (Angstrom)
    lens observer at these wavelengths/(1+zl) should correspond to the wavelengths for us
    I can get flux density at each of these filters eff wavelength w & wo dust
    the filters aren't terribly wide and throughputs are flat, will approximate mags using just eff wavelength
    that should get me an approximate vec shift (E(105-160),A160) I want w Av ~ 1 in the lens plane
    """
    # the intrinsic flux densities for lens observer at the corresponding wavelengths to bands we see
    f160 = model.flux(t, [16000 / (1 + zl)])
    f105 = model.flux(t, [10500 / (1 + zl)])
    # dusty flux densities
    dustyf160 = dust_model.flux(t, [16000 / (1 + zl)])
    dustyf105 = dust_model.flux(t, [10500 / (1 + zl)])

    # what do the extinctions look like, A ~ mobs - m
    A160 = -2.5 * np.log10(dustyf160 / f160)
    A105 = -2.5 * np.log10(dustyf105 / f105)
    # my color mag is (x,y) ~ (f105w-f160w,f160w)
    # I want to show vector (E(105-160),A160)
    # color excess
    E = A105 - A160
    return (E[0], A160[0])
Esempio n. 19
0
def test_fit_lc_vs_snfit():
    """Test fit_lc versus snfit result for one SN."""

    # purposefully use CCM dust to match snfit
    model = sncosmo.Model(source='salt2',
                          effects=[sncosmo.CCM89Dust()],
                          effect_names=['mw'],
                          effect_frames=['obs'])

    fname = join(dirname(__file__), "data", "lc-03D4ag.list")

    data = sncosmo.read_lc(fname,
                           format='salt2',
                           read_covmat=True,
                           expand_bands=True)
    model.set(mwebv=data.meta['MWEBV'], z=data.meta['Z_HELIO'])
    result, fitted_model = sncosmo.fit_lc(data,
                                          model, ['t0', 'x0', 'x1', 'c'],
                                          bounds={
                                              'x1': (-3., 3.),
                                              'c': (-0.4, 0.4)
                                          },
                                          modelcov=True,
                                          phase_range=(-15., 45.),
                                          wave_range=(3000., 7000.),
                                          warn=False,
                                          verbose=False)

    print(result)
    assert result.ndof == 25
    assert result.nfit == 3
    assert_allclose(fitted_model['t0'], 52830.9313, atol=0.01, rtol=0.)
    assert_allclose(fitted_model['x0'], 5.6578663e-05, atol=0., rtol=0.005)
    assert_allclose(fitted_model['x1'], 0.937399344, atol=0.005, rtol=0.)
    assert_allclose(fitted_model['c'], -0.0851965244, atol=0.001, rtol=0.)

    # errors
    assert_allclose(result.errors['t0'], 0.0955792638, atol=0., rtol=0.01)
    assert_allclose(result.errors['x0'], 1.52745001e-06, atol=0., rtol=0.01)
    assert_allclose(result.errors['x1'], 0.104657847, atol=0., rtol=0.01)
    assert_allclose(result.errors['c'], 0.0234763446, atol=0., rtol=0.01)
Esempio n. 20
0
    def run(self, dataSlice, slicePoint=None):
        #get ebv of this slice
        #        dec=numpy.maximum(dataSlice['fieldDec'][0],-numpy.pi/2)
        #        co = coord.ICRS(ra=dataSlice['fieldRA'][0], dec=dec, unit=(u.rad, u.rad))

        #        co = coord.ICRS(ra=slicePoint['ra'], dec=slicePoint['dec'], unit=(u.rad, u.rad))
        ebv = ctmetric_lsst.ebvObject.calculateEbv(ra=[slicePoint['ra']],
                                                   dec=[slicePoint['dec']])
        #        ebv=sncosmo.get_ebv_from_map(co, mapdir='../data',cache=True)
        #        ebv=0.

        #check to see of metric is already available for this ebv
        label = round(ebv / self.ebvprecision)
        if label in self.metriccache:
            #if so use it
            print 'using old', ebv, label
            metric = self.metriccache[label]
        else:
            #if not create it
            print 'making new ', ebv, label
            #make outside Milky Way mag into dusted magnitude
            ccm = sncosmo.CCM89Dust()
            ccm.set(ebv=ebv)
            fn = lambda x, y: self.lightcurve.mag(x, y) - 2.5 * numpy.log10(
                ccm.propagate(
                    numpy.array([lsst_info.LSST.filterinfo[y]['wave'] * 10]),
                    numpy.array([1])))
            metric = surveymetrics.ctmetric.ControlTimeMetric(
                fn, self.lightcurve.trange(), magPrecision=self.magPrecision)
            self.metriccache[label] = metric

        #convert limiting magnitude to threshold assuming sky limit
        m5col_ = dataSlice['fiveSigmaDepth']
        mtarget = m5col_ - 2.5 * numpy.log10(self.limitingsnr / 5.)
        mjds = dataSlice['expMJD']
        bands = dataSlice['filter']

        #calculate
        return metric.calcControlTime(mtarget, mjds, bands)
Esempio n. 21
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.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.)

        # 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
Esempio n. 22
0
def snia(ax, band='p48g', timescale='efoldDecline', remove_nearby=True):
    """
    Please contact me if you have any questions: [email protected]
    
    Sample from SNe Ia young sample observed in the ZTF extragalactic high-cadence
    partnership experiment. We use 121 ``normal'' SNe Ia from 2018 (including 
    normal, 91T-like, and 91bg-like SNe).
    Light curves presented in Yao et al. (2019)
    
    Parameters:
    -----------
    band: 
        'p48g': use g band ZTF data
        'p48r': use r band ZTF data
        'swope2::v', 'f555w', ...: use the SALT2 (Guy et al 2007) tool to estimate light curves in other bands
    
    timescale: 
        'efoldDecline': plot the rest-frame duration for the flux to drop from peak to 1/e*peak
        [other options TBD]
        
    remove_nearby [bool]: 
        If True, remove two SNe with z < 0.02 (ZTF18aasdted and ZTF18abgmcmv),
        since their absolute peak luminosity are largely affected by the local 
        group peculiar velocity.
    """
    from snia_funcs import add_ZTFfilters, mylinear_fit

    cwd = os.getcwd()
    datafile = cwd[:-4] + 'data/snia/' + band + '_' + timescale + '.csv'
    tbfile = cwd[:-4] + 'data/snia/Yao2019_catalog.csv'
    try:
        os.stat(datafile)
    except:
        tb = pd.read_csv(tbfile)
        add_ZTFfilters()
        zp_temp = 26.325

        Mpeaks = np.zeros(len(tb))
        Mpeaks_unc = np.zeros(len(tb))
        Tdeclines = np.zeros(len(tb))

        for i in range(len(tb)):
            name = tb['name'].values[i]
            lcfile = cwd[:-4] + 'data/snia/lightcurve/' + name + '.csv'
            z = tb['z'].values[i]
            z_unc = tb['z_unc'].values[i]
            ebv = tb['E_B_V_SandF'].values[i]

            mytb = pd.read_csv(lcfile)
            lcband = mytb['band'].values
            Fratio = mytb['Fratio'].values
            Fratio_unc = mytb['Fratio_unc'].values
            zp = np.ones(len(mytb)) * zp_temp
            zpsys = ['ab'] * len(mytb)
            time = mytb['jdobs'].values
            lc = Table(
                data=[time, lcband, Fratio, Fratio_unc, zp, zpsys],
                names=['time', 'band', 'flux', 'fluxerr', 'zp', 'zpsys'])

            dust = sncosmo.CCM89Dust()
            model = sncosmo.Model(source='salt2',
                                  effects=[dust],
                                  effect_names=['mw'],
                                  effect_frames=['obs'])
            model.set(z=z, mwebv=ebv, mwr_v=3.1)
            res, fitted_model = sncosmo.fit_lc(lc,
                                               model, ['t0', 'x0', 'x1', 'c'],
                                               bounds={
                                                   'x1': (-10., 10.),
                                                   'c': (-5., 5.)
                                               })

            t0jd_B = res.parameters[1]  # B band maximum light epoch
            t0jd_B_unc = res['errors']['t0']

            ta = np.round(t0jd_B - 25, 2) + 0.01
            tgrid = np.linspace(ta, ta + 75, 100 * 100 + 1)
            fitted_band = fitted_model.bandflux(band,
                                                tgrid,
                                                zp=zp_temp,
                                                zpsys='ab')

            # estimate peak epoch and apparent magnitude
            ixx = np.argsort(fitted_band)
            t_max = tgrid[ixx[-1]]
            fratio_max = fitted_band[ixx[-1]]
            appmag_max = -2.5 * np.log10(fratio_max)
            appmag_around = fitted_model.bandmag(
                band, 'ab', [t_max - t0jd_B_unc, t_max + t0jd_B_unc]) - zp_temp
            appmag_max_unc = (np.sum(appmag_around) - 2 * appmag_max) / 2.

            # estimate extinction corrected peak epoch apparent magnitude
            wave_eff = sncosmo.get_bandpass(band).wave_eff
            Aband = extinction.ccm89(np.array([wave_eff]), 3.1 * ebv, 3.1)[0]
            appmag0_max = appmag_max - Aband

            # estimate extinction corrected peak epoch absolute magnitude
            D = cosmo.luminosity_distance([z])[0].value * 1e+6  # in pc
            D_unc = (
                cosmo.luminosity_distance([z + z_unc])[0].value -
                cosmo.luminosity_distance([z - z_unc])[0].value) / 2. * 1e+6
            dis_mod = 5 * np.log10(D / 10)
            dis_mod_unc = 5 / np.log(10) / D * D_unc
            absmag0_max = appmag0_max - dis_mod
            absmag0_max_unc = np.sqrt(appmag_max_unc**2 + dis_mod_unc**2)
            Mpeaks[i] = absmag0_max
            Mpeaks_unc[i] = absmag0_max_unc

            # estimate the characteristic timescale
            if timescale == 'efoldDecline':
                fratio_end = fratio_max / np.e
                ind = np.argsort(abs(fitted_band - fratio_end))
                ix_end = ind[ind > ixx[-1]][0]
                t_end = tgrid[ix_end]
                time_duration = t_end - t_max
                Tdeclines[i] = time_duration

        tbnew = Table(data=[
            tb['name'].values, tb['z'].values, Mpeaks, Mpeaks_unc, Tdeclines
        ],
                      names=['name', 'z', 'mag', 'mag_unc', 'timescale'])
        tbnew.write(datafile, overwrite=True)

    data = pd.read_csv(datafile)
    data = data[data.z > 0.02]
    x = data['timescale'].values / (1 + data['z'].values)
    y = data['mag'].values
    y_err = data['mag_unc'].values

    # plt.figure(figsize=(12, 8))
    # ax = plt.subplot(111)

    # plot individual data points
    ax.errorbar(x, y, y_err, fmt='.k')

    # plot the grey contour
    slope, e_slope, intercept = mylinear_fit(x, y, y_err, npar=2)
    nstd = 5.  # to draw 5-sigma intervals
    slope_up = slope + nstd * e_slope
    slope_dw = slope - nstd * e_slope
    x_fit = np.linspace(min(x) - 0.5, max(x) + 0.5, 100)
    # fit = slope * x_fit+ intercept
    fit_up = slope_up * x_fit + intercept
    fit_dw = slope_dw * x_fit + intercept
    ax.fill_between(x_fit,
                    fit_up,
                    fit_dw,
                    color='grey',
                    alpha=.25,
                    label="5-sigma interval")
Esempio n. 23
0
    def __init__(self,survey_fields=None, simlib_file=None,simlib_obs_sets=None, c_pdf='Normal',\
       c_params=[-0.05,0.2],x1_pdf='Normal',x1_params=[0.5,1.0],\
       t0min = 56525.0,t0max=57070.0,NumSN = 500,minNumEpochs = 5,minNumFilters = 3, minSNR = 4.0,\
      cosmo=None,alpha=0.14,beta=3.2,deltaM=0.0,zp_off=[0.0,0.0,0.0,0.0]):
        '''Input: 
			survey_fields:dict, survey fields to generate z dist, values should be [area,zmin,zmax,dndz func,time ]
			simlib_file: str, snana simlib  
			simlib_obs_sets= observation library
			c_pdf and x1_pdf: str, either 'Normal' or 'SkewNormal'
			c_params and x1_params: list, hyperparams for 'Normal' [mean,var] or 'SkewNormal' [mean,var,skew]
			t0min: float
			t0max: float
			NumSN: int, number of SN to simulate and fit
			minNumEpochs: int, minNumFilters: int, minSNR: int,  selection cut: require minNumEpochs in at least minNumFilters with SNR>minSNR 
		'''
        self.t0min = t0min
        self.t0max = t0max
        self.NumSN = NumSN
        self.minNumEpochs = minNumEpochs
        self.minNumFilters = minNumFilters
        self.minSNR = minSNR
        self.alpha = alpha
        self.beta = beta
        self.deltaM = deltaM
        self.zp_off = zp_off

        if survey_fields == None:
            self.survey_fields = self.DES_specific_zdist()
        else:
            self.survey_fields = survey_fields
        if cosmo == None:
            self.cosmo = FlatLambdaCDM(H0=70.0, Om0=0.3)
        else:
            self.cosmo = cosmo
        self.totz = self.get_zdist()
        print "Total number of sn to be simulated:", len(self.totz)

        start = time.time()
        if simlib_file:
            self.simlib_meta, self.simlib_obs_sets = self.read_simlib(
                simlib_file)
        else:
            self.simlib_obs_sets = simlib_obs_sets
        end = time.time()
        if bench: print "Read simlib file in ", end - start, "secs"

        self.c_pdf = c_pdf
        self.c_params = c_params
        self.x1_pdf = x1_pdf
        self.x1_params = x1_params

        start = time.time()
        self.generate_random_c_x1()
        end = time.time()
        if bench: print "c-x1 generated in ", end - start, "secs"
        self.generate_t0()

        #EJ: Note the model needs to be downloaded at this point - is there
        #anyway we can avoid this for users who are not online?
        dust = sncosmo.CCM89Dust()
        self.model = sncosmo.Model(source='salt2-extended',effects=[dust],effect_names=['mw'],\
        effect_frames=['obs'])
        self.get_parameter_list()
        self.generate_lcs()
        start = time.time()
        self.fit_lcs()
        end = time.time()
        if bench: print "Fitting took", end - start, "secs"

        if setplot:
            for ii in range(len(self.fit_results)):
                plt.plot(self.simx0[ii],self.fit_results[ii]['parameters'][2],\
                linestyle='None', marker="o")
            plt.savefig('x0.png')
            plt.close()
            for ii in range(len(self.fit_results)):
                plt.plot(self.simx1[ii],self.fit_results[ii]['parameters'][3],\
                linestyle='None', marker="o")
            plt.savefig('x1.png')
            plt.close()
            for ii in range(len(self.fit_results)):
                plt.plot(self.simc[ii],self.fit_results[ii]['parameters'][4],\
                linestyle='None', marker="o")
            plt.savefig('c.png')
            plt.close()

        #print self.fit_results[0].keys(), self.fit_results[0]['param_names'], self.fit_results[0]['parameters']
        #print self.fit_results[0]['parameters']
        #print self.fit_results[0]['covariance'], self.fit_results[0]['covariance'].shape
        #print self.totz[0],self.simt0[0], self.simx0[0], self.simx1[0], self.simc[0]
        #print self.lcs[0][0]
        #print self.lcs[0][0]
        #print self.fitted_model[0]
        sncosmo.plot_lc(self.lcs[0][0],
                        model=self.fitted_model[0],
                        errors=self.fit_results[0].errors)
        plt.savefig("lc.png")
Esempio n. 24
0
def analyze():
    pkl_file = open('ccm.pkl', 'r')
    amed = pickle.load(pkl_file)
    pkl_file.close()

    synlam = numpy.array([[3300.00, 3978.02], [3978.02, 4795.35],
                          [4795.35, 5780.60], [5780.60, 6968.29],
                          [6968.29, 8400.00]])

    synname = ['U', 'B', 'V', 'R', 'I']

    synbands = []

    for name, lams in zip(synname, synlam):
        synbands.append(sncosmo.Bandpass(lams, [1., 1.], name='tophat' + name))

    model_nodust = sncosmo.Model(source='hsiao')
    flux_nodust = model_nodust.bandflux(synbands, 0.)

    av = numpy.exp(
        numpy.arange(numpy.log(0.005),
                     numpy.log(1.8) + 0.001,
                     numpy.log(1.8 / 0.005) / 25))
    rv = numpy.exp(
        numpy.arange(numpy.log(2.1),
                     numpy.log(6.9) + 0.001,
                     numpy.log(6.9 / 2.1) / 50))

    avs = []
    ebvs = []
    rvs = []
    AX = []

    for a in av:
        for r in rv:
            dust = sncosmo.CCM89Dust()
            dust.set(ebv=a / r, r_v=r)
            model = sncosmo.Model(source='hsiao',
                                  effects=[dust],
                                  effect_names=['host'],
                                  effect_frames=['rest'])
            AX.append(-2.5 *
                      numpy.log10(model.bandflux(synbands, 0.) / flux_nodust))
            avs.append(a)
            ebvs.append(a / r)
            rvs.append(r)

    avs = numpy.array(avs)
    ebvs = numpy.array(ebvs)
    AX = numpy.array(AX)
    rvs = numpy.array(rvs)

    diff = AX - (amed[0][None,:]*avs[:,None]+ amed[1][None,:] * avs[:,None]**2 \
        +amed[2][None,:]*ebvs[:,None]+ amed[3][None,:] * ebvs[:,None]**2 \
        +amed[4][None,:] * (avs*ebvs)[:,None] \
        +amed[5][None,:] * (avs**3)[:,None] \
        +amed[6][None,:] * (ebvs**3)[:,None] \
        +amed[7][None,:] * ((avs**2)*ebvs)[:,None] \
        +amed[8][None,:] * (avs*(ebvs**2))[:,None] \
        )

    print numpy.max(numpy.abs(diff))
    arg = numpy.argmax(numpy.abs(diff))
    print avs[arg / 5], ebvs[arg / 5]
    print diff[arg / 5]

    print avs.max()
    wav = avs == 1.8
    for i in xrange(5):
        plt.plot(rvs[wav], diff[wav, i], label=synname[i])
    plt.ylabel(r'$\Delta A$')
    plt.xlabel(r'$R$')
    plt.legend()
    pp = PdfPages('output18/dfitz.pdf')
    plt.savefig(pp, format='pdf')
    pp.close()
    plt.close()
Esempio n. 25
0
        def save_FINAL_spectrum(self):
            if (not hasattr(self, 'final_mangled_spec')):
                print(
                    "Mangled spectrum not available. First you need to mangle the spectrum calling self.mangle_spectrum()"
                )
            if (not hasattr(self, 'FINALspec_path')):
                self.create_FINALspec_folder()

            flux = self.final_mangled_spec['flux']
            fluxerr = self.final_mangled_spec['fluxerr']

            sn_info = self.load_final_info()
            MWdust = sncosmo.CCM89Dust()
            Hostdust = sncosmo.CCM89Dust()
            r_v = 3.1
            z = sn_info['z'].values[0]

            wls = self.ext_spec['wls']
            wls_restframe = self.ext_spec['wls'] / (1 + z)

            # MW corrections in SN restframe
            MW_ebv = sn_info['EBV_MW'].values[0]
            MWdust.parameters = [MW_ebv, r_v]
            MW_extinction_perc = MWdust.propagate(wls_restframe,
                                                  np.ones(len(flux)))

            # Host corrections in SN restframe
            Host_ebv = sn_info['EBV_host'].values[0]
            Hostdust.parameters = [Host_ebv, r_v]
            Host_extinction_perc = Hostdust.propagate(wls, np.ones(len(flux)))

            dist = 10**(mycosmo.distmod(z).value / 5. + 1)
            To_abs_lum = (dist / 10.)**2

            self.final_spec_wls = wls_restframe
            self.HostCorr_spec_flux = To_abs_lum * flux
            self.HostCorr_spec_fluxerr = To_abs_lum * fluxerr

            self.HostNOTCorr_spec_flux = To_abs_lum * flux * Host_extinction_perc
            self.HostNOTCorr_spec_fluxerr = To_abs_lum * fluxerr * Host_extinction_perc

            self.as_observed_spec_flux = flux * Host_extinction_perc * MW_extinction_perc
            self.as_observed_spec_fluxerr = fluxerr * Host_extinction_perc * MW_extinction_perc

            spec_number = self.phot4mangling.spec_mjd.values[
                0]  # self.phot4mangling.index.values[0]

            for path_fold in ['', '/HostNotCorr/', '/as_observed/']:
                path = self.FINALspec_path + path_fold
                if 'FL' in self.spec_file:
                    fout = open(
                        path + self.spec_file.replace('_spec_extended_FL.txt',
                                                      '_FINAL_spec_FL.txt'),
                        'w')
                elif 'SMOOTH' in self.spec_file:
                    fout = open(
                        path +
                        self.spec_file.replace('_spec_extended_SMOOTH.txt',
                                               '_FINAL_spec_SMOOTH.txt'), 'w')
                elif 'SNF' in self.spec_file:
                    fout = open(
                        path + self.spec_file.replace('_spec_extended_SNF.txt',
                                                      '_FINAL_spec_SNF.txt'),
                        'w')
                else:
                    fout = open(path + '/%.2f_FINAL_spec.txt' % spec_number,
                                'w')
                fout.write('#wls\tflux\tfluxerr\n')
                if path_fold == '':
                    for w, f, ferr in zip(self.final_spec_wls,
                                          self.HostCorr_spec_flux,
                                          self.HostCorr_spec_fluxerr):
                        fout.write('%E\t%E\t%E\n' % (w, f, ferr))
                    fout.close()
                elif path_fold == '/HostNotCorr/':
                    for w, f, ferr in zip(self.final_spec_wls,
                                          self.HostNOTCorr_spec_flux,
                                          self.HostNOTCorr_spec_fluxerr):
                        fout.write('%E\t%E\t%E\n' % (w, f, ferr))
                    fout.close()

                elif path_fold == '/as_observed/':
                    for w, f, ferr in zip(self.final_spec_wls,
                                          self.as_observed_spec_flux,
                                          self.as_observed_spec_fluxerr):
                        fout.write('%E\t%E\t%E\n' % (w, f, ferr))
                    fout.close()
Esempio n. 26
0
def SNMC(df, name, window=652 / 365, scale=1e6):
    """
    df should be the full data frame, with properties of all the targets
    it will be indexed with name for single target by 'our survey name' inside the function
    Using the SN rates with window of time to generate N SNe, [N/yr]*1.8 yr
    The window ~ final - first observation from read_slate
    """
    avg_NIa = np.mean(df['NIa'])
    avg_eNIa = np.mean(df['e_NIa'])
    avg_Ncc = np.mean(df['Ncc'])
    avg_eNcc = np.mean(df['e_Ncc'])
    targ = df[df[' Our Survey Name '] == name]
    zS, mu = targ['zS'], targ['mu']
    NIa = targ['NIa']
    Ncc = targ['Ncc']
    e_NIa = targ['e_NIa']
    e_Ncc = targ['e_Ncc']
    """
    if pd.isna(NIa):
        # use the avg if rate not available, should only apply to SWELLSJ0841+3824
        print('using avg SN rates for',name)
        NIa,e_NIa = avg_NIa,avg_eNIa
    """
    # scale up rates to large enough numbers to get multiple models to plant
    NIa *= scale
    e_NIa *= scale
    Ncc *= scale
    e_Ncc *= scale
    # select a rate
    NIa = np.random.normal(NIa, e_NIa)
    if NIa < 0:
        NIa = 0

    # use window to get number from rates
    if type(window) == dict:
        window = window['window']
        window = window.days / 365
    nIa = NIa * window  # NIa [/yr], window ~ 652 days, n [expected number of Ia in window]
    ncc = Ncc * window

    # dusts
    """
    for a review of dust http://www.astronomy.ohio-state.edu/~pogge/Ast871/Notes/Dust.pdf
    Observationally, RV ranges between 2 and 6, but most often one finds the interstellar extinction law
    assumed by people as adopting one of two “typical” values for RV:
    RV=3.1, typical of the Diffuse ISM.
    RV=5, typical of dense (molecular) clouds. 
    """
    mwdust = sncosmo.CCM89Dust()
    mwdust.set(ebv=0, r_v=3.1)  # these are the defaults of CCM89Dust()
    hostdust = sncosmo.CCM89Dust()
    hostdust.set(ebv=0, r_v=3.1)
    import sfdmap
    dustmap = sfdmap.SFDMap(
        '/home/oconnorf/miniconda/lib/python3.7/site-packages/mwdust/dust_maps'
    )
    # using  Schlegel, Finkbeiner & Davis (1998) MW dust map to set EBV
    # get ra and dec of the SN ~ target
    ra = df['ra']
    dec = df['dec']
    print(ra, dec)
    #ra,dec=0.0,0.0
    ebv = dustmap.ebv(ra, dec)
    mwdust.set(ebv=ebv)

    # Luminosity Functions: Goldstein 2019 Table 1, MB Vega, https://arxiv.org/pdf/1809.10147.pdf
    band, sys = 'bessellb', 'vega'
    MIa, sigmaIa = -19.23, 0.1
    MIIp, sigmaIIp = -16.9, 1.12
    MIIL, sigmaIIL = -17.46, 0.38
    MIIn, sigmaIIn = -19.05, 0.5
    MIbc, sigmaIbc = -17.51, 0.74
    # Luminosity Functions: Converted to AB Mag System, http://www.astronomy.ohio-state.edu/~martini/usefuldata.html, Blanton et al. 2007
    # B-Band m_AB - m_Vega ~ -0.09
    band, sys = 'bessellb', 'ab'
    dm = -0.09
    MIa += dm
    MIIp += dm
    MIIL += dm
    MIIn += dm
    MIbc += dm

    # fractions core collapse: Eldridge 2013, https://arxiv.org/abs/1301.1975
    # Volume limited ~ 30 Mpc couple hundred transients in the sample
    fracIb, fracIc, fracIIp, fracIIL, fracIIn, fracIIb, fracIIpec = 0.09, 0.17, 0.55, 0.03, .024, 0.121, 0.01
    # my combinations of eldridges subtypes to goldsteins
    fracIbc = fracIb + fracIc
    fracIIL = fracIIL + fracIIpec + fracIIb
    # if you want the check on CC fractions
    fracs = [fracIIp, fracIIL, fracIIn, fracIbc]
    # np.sum(fracs)
    """
    Another possible source for fractions...
    Fractions core collapse: Smith 2010, https://arxiv.org/pdf/1006.3899.pdf 
    Volume limited ~ 60 Mpc sample from LOSS
    """

    # Stretch and Color Ia parameter distributions
    c = np.linspace(-0.3, 0.5, 1000)
    cdist = [f_asymmGauss(ci, -0.054, .043, 0.101) for ci in c]
    dc = (max(c) - min(c)) / len(c)
    cps = np.array(cdist) * dc
    tmp = (1 - np.sum(cps)) / len(c)
    cps = [i + tmp for i in cps]

    x1 = np.linspace(-3.0, 2.0, 1000)
    x1dist = [f_asymmGauss(xi, 0.973, 1.472, 0.222) for xi in x1]
    dx1 = (max(x1) - min(x1)) / len(x1)
    x1ps = np.array(x1dist) * dx1
    tmp = (1 - np.sum(x1ps)) / len(x1)
    x1ps = [i + tmp for i in x1ps]

    # The models
    Iamodels = []
    CCmodels = []
    IIpmodels, IILmodels, IInmodels, Ibcmodels = [], [], [], []
    # The mags if want to see those (without magnification)
    magIas = []
    magIIps, magIILs, magIIns, magIbcs = [], [], [], []
    cs, x1s = [], []
    for i in range(int(nIa)):
        model = sncosmo.Model(source='salt2-extended',
                              effects=[hostdust, mwdust],
                              effect_names=['host', 'mw'],
                              effect_frames=['rest', 'obs'])  # Ia
        magIa = np.random.normal(MIa, sigmaIa)
        magIas.append(magIa)
        # lensing magnification
        mabs = magIa - 2.5 * np.log10(mu)
        t0 = np.random.uniform(0, int(window * 365))
        # stretch
        list_of_candidates, number_of_items_to_pick, probability_distribution = x1, 1, x1ps
        x1draw = choice(list_of_candidates,
                        number_of_items_to_pick,
                        p=probability_distribution)
        x1s.append(x1draw)
        # color
        list_of_candidates, number_of_items_to_pick, probability_distribution = c, 1, cps
        cdraw = choice(list_of_candidates,
                       number_of_items_to_pick,
                       p=probability_distribution)
        cs.append(cdraw)
        # set the values
        model.set(z=zS, t0=t0, c=cdraw, x1=x1draw)
        model.set_source_peakabsmag(mabs, band, sys)
        Iamodels.append(model)
    for i in range(int(fracIIp * ncc)):
        model = sncosmo.Model(source='s11-2005lc',
                              effects=[hostdust, mwdust],
                              effect_names=['host', 'mw'],
                              effect_frames=['rest', 'obs'])  # IIp
        magIIp = np.random.normal(MIIp, sigmaIIp)
        magIIps.append(magIIp)
        mabs = magIIp - 2.5 * np.log10(mu)
        t0 = np.random.uniform(0, int(window * 365))
        model.set(z=zS, t0=t0)
        model.set_source_peakabsmag(mabs, band, sys)
        IIpmodels.append(model)
    CCmodels.append(IIpmodels)
    for i in range(int(fracIIL * ncc)):
        model = sncosmo.Model(source='nugent-sn2l',
                              effects=[hostdust, mwdust],
                              effect_names=['host', 'mw'],
                              effect_frames=['rest', 'obs'])  # IIL
        magIIL = np.random.normal(MIIL, sigmaIIL)
        magIILs.append(magIIL)
        mabs = magIIL - 2.5 * np.log10(mu)
        t0 = np.random.uniform(0, int(window * 365))
        model.set(z=zS, t0=t0)
        model.set_source_peakabsmag(mabs, band, sys)
        IILmodels.append(model)
    CCmodels.append(IILmodels)
    for i in range(int(fracIIn * ncc)):
        model = sncosmo.Model(source='nugent-sn2n',
                              effects=[hostdust, mwdust],
                              effect_names=['host', 'mw'],
                              effect_frames=['rest', 'obs'])  # IIn
        magIIn = np.random.normal(MIIn, sigmaIIn)
        magIIns.append(magIIn)
        mabs = magIIn - 2.5 * np.log10(mu)
        t0 = np.random.uniform(0, int(window * 365))
        model.set(z=zS, t0=t0)
        model.set_source_peakabsmag(mabs, band, sys)
        IInmodels.append(model)
    CCmodels.append(IInmodels)
    for i in range(int(fracIbc * ncc)):
        model = sncosmo.Model(source='nugent-sn1bc',
                              effects=[hostdust, mwdust],
                              effect_names=['host', 'mw'],
                              effect_frames=['rest', 'obs'])  # Ibc
        magIbc = np.random.normal(MIbc, sigmaIbc)
        magIbcs.append(magIbc)
        mabs = magIbc - 2.5 * np.log10(mu)
        t0 = np.random.uniform(0, int(window * 365))
        model.set(z=zS, t0=t0)
        model.set_source_peakabsmag(mabs, band, sys)
        Ibcmodels.append(model)
    CCmodels.append(Ibcmodels)

    return [Iamodels, CCmodels]
Esempio n. 27
0
                          minsnr=minsnr)
    reschar = ResChar.fromSNCosmoRes(resfit)
    return snid, reschar


snana_eg = SNANASims.fromSNANAfileroot(
    snanafileroot='LSST_Ia',
    location='/Users/rbiswas/data/LSST/SNANA_data/MINION_1016_10YR_DDF_v2/',
    coerce_inds2int=False)

if __name__ == '__main__':
    snana_eg = SNANASims.fromSNANAfileroot(
        snanafileroot='LSST_Ia',
        location='/Users/rbiswas/data/LSST/SNANA_data/MINION_1016_10YR_DDF_v2/',
        coerce_inds2int=False)
    dust = sncosmo.CCM89Dust()
    model = sncosmo.Model(source='salt2-extended',
                          effects=[dust, dust],
                          effect_names=['host', 'mw'],
                          effect_frames=['rest', 'obs'])
    for i in range(3):
        try:
            snid, r = inferParams(snana_eg,
                                  model,
                                  sncosmo.fit_lc,
                                  i,
                                  minsnr=3.)
            with open('results.dat',
                      'w') as fh:  # Should Not be a text file when improved!
                write_str = snid
                write_str += ','.join(map(str, r.parameters))
Esempio n. 28
0
def dofit(datfile='nebra_bestphot.dat',
          z=2.00,
          dz=0.02,
          t0=57575.,
          dt0=20.0,
          x1=None,
          c=None,
          model='Ia',
          noUV=True,
          debug=False):
    # TODO : read in the redshift, etc from the header.

    from .colorcolorfig import SubClassDict_SNANA
    # read in the obs data
    sn = ascii.read(datfile,
                    format='commented_header',
                    header_start=-1,
                    data_start=0)

    if model == 'Ia':
        # define SALT2 models and set initial guesses for z and t0
        if noUV:
            salt2ex = sncosmo.Model(source='salt2')
        else:
            salt2ex = sncosmo.Model(source='salt2-extended')
        salt2ex.source.set_peakmag(0., 'bessellb', 'ab')
        x0_AB0 = salt2ex.get('x0')
        salt2ex.set(z=z, t0=t0, x1=0.1, c=-0.2)
        # salt2ex.set( z=1.33, t0=56814.6, hostebv=0.05, hostr_v=3.1 )

        # Do a bounded fit :
        # salt2res, salt2fit = sncosmo.fit_lc( sn, salt2, ['z','t0','x0','x1','c'], bounds={'z':(1.28,1.37),'t0':(56804,56824)} )
        varlist = varlist = ['z', 't0', 'x0']
        bounds = {'z': (z - dz, z + dz), 't0': (t0 - dt0, t0 + dt0)}
        if x1 is not None:
            salt2ex.set(x1=x1)
            bounds['x1'] = (x1 - 1e-6, x1 + 1e-6)
            varlist.append('x1')
        else:
            bounds['x1'] = (-5, 5)
            varlist.append('x1')
        if c is not None:
            salt2ex.set(c=c)
        else:
            bounds['c'] = (-0.5, 3.0)
            varlist.append('c')

        res, fit = sncosmo.fit_lc(sn, salt2ex, varlist, bounds)

        x0 = fit.get('x0')
        z = fit.get('z')
        mB = -2.5 * np.log10(x0 / x0_AB0)
        distmod = mB - MBmodel
        deltamuLCDM = distmod - dm(z)
        print("mB = %.2f" % mB)
        print("dist.mod. = %.2f" % distmod)
        print("Delta.mu_LCDM = %.2f" % deltamuLCDM)

        chi2 = res.chisq
        ndof = res.ndof
        pval = chisqprob(chi2, ndof)

        if ndof > 0:
            print("chi2/dof= %.3f" % (chi2 / float(ndof)))
            print("p-value = %.3f" % pval)
        else:
            print("chi2/dof= %.3f/%i" % (chi2, ndof))
            print("p-value = %.3f" % pval)

        print("z = %.3f" % fit.get('z'))
        print("t0 = %.3f" % fit.get('t0'))
        print("x0 = %.3e" % fit.get('x0'))
        print("x1 = %.3f" % fit.get('x1'))
        print("c = %.3f" % fit.get('c'))

    elif model.lower() in ['cc', 'ib', 'ic', 'ii', 'ibc', 'iip', 'iin']:
        # remove the blue filters from the sn data
        bandlist = sn['filter'].data
        igood = np.array([band.lower().startswith('f1') for band in bandlist])
        sn = sn.copy()[igood]

        # define a host-galaxy dust model
        dust = sncosmo.CCM89Dust()
        version = '1.0'

        if model.lower() == 'cc': classlist = ['Ib', 'Ic', 'IIP', 'IIn']
        elif model.lower() == 'ii': classlist = ['IIP', 'IIn']
        elif model.lower() == 'ibc': classlist = ['Ibc']
        else: classlist = [model]

        # find the best-fit from each CC sub-class
        chi2list, reslist, fitlist = [], [], []
        for snclass in classlist:
            for modname in SubClassDict_SNANA[snclass.lower()]:
                Av = 0.2
                modkey = (sncosmo.Source, modname, version)
                if modkey not in sncosmo.registry._loaders: continue
                ccmodel = sncosmo.Model(source=modname,
                                        effects=[dust],
                                        effect_names=['host'],
                                        effect_frames=['rest'])
                ccmodel.set(z=z, t0=t0, hostr_v=3.1, hostebv=Av / 3.1)
                # Do a bounded fit :
                res, fit = sncosmo.fit_lc(sn,
                                          ccmodel,
                                          ['z', 't0', 'amplitude', 'hostebv'],
                                          debug=debug,
                                          bounds={
                                              'z': (z - dz, z + dz),
                                              't0': (t0 - dt0, t0 + dt0),
                                              'hostebv': (0.0, 1.0)
                                          })

                chi2 = res.chisq
                ndof = res.ndof
                pval = chisqprob(chi2, ndof)

                print("%s  chi2/dof= %.3f  p=%.3f" %
                      (modname, chi2 / float(ndof), pval))
                chi2list.append(chi2 / float(ndof))
                reslist.append(res)
                fitlist.append(fit)
        ichi2min = np.argmin(chi2list)
        res, fit = reslist[ichi2min], fitlist[ichi2min]
    else:  # 'nugent-sn91bg'
        # remove the blue filters from the sn data
        bandlist = sn['filter'].data
        igood = np.array([band.startswith('f1') for band in bandlist])
        sn = sn.copy()[igood]

        # define a host-galaxy dust model
        dust = sncosmo.CCM89Dust()
        version = '1.0'

        Av = 0.2
        altmodel = sncosmo.Model(source=model,
                                 effects=[dust],
                                 effect_names=['host'],
                                 effect_frames=['rest'])
        altmodel.set(z=z, t0=t0, hostr_v=3.1, hostebv=Av / 3.1)
        # Do a bounded fit :
        res, fit = sncosmo.fit_lc(sn,
                                  altmodel,
                                  ['z', 't0', 'amplitude', 'hostebv'],
                                  debug=debug,
                                  bounds={
                                      'z': (z - dz, z + dz),
                                      't0': (t0 - dt0, t0 + dt0),
                                      'hostebv': (0.0, 1.0)
                                  })

        chi2 = res.chisq
        ndof = res.ndof
        pval = chisqprob(chi2, ndof)

        print("%s  chi2/dof= %.3f  p=%.3f" % (model, chi2 / float(ndof), pval))

    return (sn, fit, res)
Esempio n. 29
0
 def setup_class(self):
     self.model = sncosmo.Model(source=flatsource(),
                                effects=[sncosmo.CCM89Dust()],
                                effect_frames=['obs'],
                                effect_names=['mw'])
Esempio n. 30
0
def light_curves_salt2(z: float, filters: list, peak: float = None, days: Union[tuple, list, np.ndarray] = (0, 85),
                       show: bool = True, rise_time: float = None, ebv_mw: float = 0, ebv_host: float = 0.,
                       x1: float = None, output_path: str = None, output_title: str = None, day_markers: list = None,
                       fil_peak='bessellb', r_v: float = 2.3):
    """ Produces light curves, in the provided filters, for a Type Ia supernova using the SALT2 models as implemented 
    in sncosmo. 
    :param z: Redshift of source.
    :param filters: Filters to obtain light curves in. Must be in the sncosmo Registry.
    :param peak: Peak (ie lowest) absolute magnitude, in the filter given by fil_peak, to calibrate curves to.
    :param days: Either an array of times (in days) to calculate the light curves over, or a tuple describing the range
        of days, ie (first_day, last_day)
    :param show: Show plot onscreen?
    :param rise_time: Rest-frame time, from beginning of SN to peak magnitude, in days.
    :param ebv_mw: Reddening parameter E(B-V), using S&F11 law, for the Milky Way along the SN's line-of-sight.
    :param ebv_host: Reddening parameter E(B-V), using S&F11 law, for the host galaxy.
    :param x1: SALT2 light curve stretch parameter. See SALT2 documentation for further information.
    :param output_path: Path to which to save output. If None, does not save.
    :param output_title: Title to give output plot and table.
    :param day_markers: List of times (in days) to mark on plot, eg observation dates.
    :param fil_peak: Filter in which to set the peak absolute magnitude; usually reported in B or V.
    :return: mag_table, model
        mag_table: an astropy.table.Table with the times, in days, and the magnitudes in each filter.
        model: the entire sncosmo model instance.
    """
    if output_path is not None and output_path[-1] != '/':
        output_path += '/'
    u.mkdir_check(output_path)
    # Find time at which model begins and time of peak.
    t_first, t_peak = find_model_times(source='salt2-extended', z=z, fil=fil_peak, show=False)
    # If both are None, the model is invalid over these wavelengths
    if t_first is t_peak is None:
        return None, None
    # Set up model in sncosmo.
    dust_mw = sncosmo.F99Dust()
    dust_host = sncosmo.CCM89Dust()
    model = sncosmo.Model(source='salt2-extended', effects=[dust_mw, dust_host],
                          effect_names=['mw', 'host'],
                          effect_frames=['obs', 'rest'])
    model.set(x1=x1)
    # If a rise time is not given, allow the model to determine this itself.
    if rise_time is None:
        if t_peak <= 0:
            model.set(z=z, t0=-t_first, mwebv=ebv_mw, hostebv=ebv_host, hostr_v=r_v)
        else:
            model.set(z=z, t0=0, mwebv=ebv_mw, hostebv=ebv_host, hostr_v=r_v)
    elif rise_time == -1:
        model.set(z=z, t0=t_first, mwebv=ebv_mw, hostebv=ebv_host, hostr_v=r_v)
    else:
        # Correct rise time to observer frame
        rise_time_obs = rise_time * (1 + z)
        model.set(z=z, t0=rise_time_obs - t_peak, mwebv=ebv_mw, hostebv=ebv_host, hostr_v=r_v)
    print(model)
    # Set peak absolute magnitude of model.
    if peak is not None:
        model.set_source_peakabsmag(peak, fil_peak, 'ab')
    if type(days) is tuple:
        # Set up array of times.
        days = np.arange(days[0], days[1] + 1, 0.1)

    mags_filters = table.Table()
    mags_filters['days'] = days
    maxes = []
    t_peaks = []
    peaks = []
    for f in filters:
        # Get light curve.
        mags = model.bandmag(f, 'ab', days)
        # If the light curve is mostly flat, the model has probably broken down.
        if np.sum(mags == mags[0]) < 0.9 * len(mags):
            # If this is False, the entire light curve must be nan, and we'll get nothing useful out of it.
            if not np.isnan(np.nanmax(mags)):
                # Collect peak (lowest) magnitudes, peak times, and maximum (faintest) magnitudes for each filter.
                maxes.append(np.nanmax(mags[mags != np.inf]))
                peaks.append(np.nanmin(mags[mags != np.inf]))
                t_peaks.append(days[np.nanargmin(mags)])
                # Write light curve to table.
                mags_filters[f] = mags
                if output_path is not None or show:
                    # Plot curve.
                    plt.plot(days, mags, label=f)

    # If we have no maxima, the model has broken down.
    if len(maxes) > 0:
        # Collect this for plotting purposes.
        max_mag = np.nanmax(maxes)
        min_mag = np.nanmin(peaks)
    else:
        return None, None

    # If an output_path directory is not given and 'show' is not True, there's no point doing the plot.
    if output_path is not None or show:
        for i, t_peak in enumerate(t_peaks):
            # Plot blue lines marking the peak of each filter light curve.
            plt.plot([t_peak, t_peak], [max_mag + 1, min_mag - 1], c='blue')

        if day_markers is not None:
            for other_day in day_markers:
                # Plot red lines marking the observation dates.
                plt.plot([other_day, other_day], [max_mag + 1, min_mag - 1], c='red')
        plt.xlabel('Time (days)')
        plt.ylabel('Magnitude')
        plt.ylim(max_mag + 1, min_mag - 1)
        plt.legend()
        if output_path is not None:
            # Save figure.
            plt.savefig(output_path + output_title + '.png')
            # Save table to csv.
            mags_filters.write(output_path + output_title + '.csv', format='ascii.csv')
        if show:
            # Show figure onscreen.
            plt.show()
        plt.close()

    return mags_filters, model