Exemple #1
0
def init_guess_breakout_exp(sn, tel, band, a2=1., maxt=5.):
    """
    initial guess for breakout phase for exponential fit

    Parameters
    ----------
    sn: snlc::getlc::SNLC object,
	SN light curve object
    tel: string, 
        telescope under consideration
    band: string, 
        band under consideration

    kwargs
    ------
    a2: float, 
    	initial guess for a2 parameter
    maxt: float,
	maximum time of breakout phase

    Returns
    -------
    dict with initial guesses
    """
    par = {}

    # discovery date
    tdisc = sn.get_dates_mjd(datetype='discover')[0]
    # first measurement
    t1 = sn.dat[tel][band].t[0]

    #    par['t0'] = 0.5 * (tdisc + t1)
    par['t0'] = t1 - 1e-2

    # convert mag to flux
    y = mag2flux(sn.dat[tel][band].m, **ref)

    # exlcude upper limits and only use first days
    mask = (sn.dat[tel][band].dm > 0.) & \
     (sn.dat[tel][band].t - par['t0'] < maxt)

    itmax = np.argmax(y[mask])

    # get measurement closest to maximum
    ymax = y[mask][itmax]
    dt = sn.dat[tel][band].t[mask][itmax] - par['t0']

    par['a2'] = a2

    # get initial guesses
    if dt > 10.:
        logging.warning('Estimated maximum more than 10 days after discovery!')

    par['a1'] = ymax / (1. - np.exp(-dt / par['a2']))
    return par
Exemple #2
0
def init_guess_arnett(sn,
                      tel,
                      band,
                      t0,
                      delay=10.,
                      y=2.,
                      subtract=lambda t: 0.):
    """
    initial guess for expansion phase model with arnett

    Parameters
    ----------
    sn: snlc::getlc::SNLC object,
	SN light curve object
    tel: string, 
        telescope under consideration
    band: string, 
        band under consideration
    t0: float, 
	estimate for explosion time
    y: float,
       estimate for tauM (a4), where y = tauM / 2 / tauNi

    kwargs
    ------
    delay: float, 
    	delay time in days when expansion should dominate.
	Flux estimated from flux corresponding to closest time
    substract: fuction pointer,
	additional flux that might contribute at time of delay

    Returns
    -------
    dict with initial guesses
    """
    par = {}

    # take discovery date as initial guess for explosion time
    par['t0'] = t0

    # get measurement closest to maximum
    it = np.argmin(np.abs(sn.dat[tel][band].t - (par['t0'] + delay)))

    # convert mag to flux
    f = mag2flux(sn.dat[tel][band].m, **ref)

    # get initial guesses
    par['a4'] = 2. * y * tauNi
    x = delay / par['a4']
    par['a3'] = (f[it] - subtract(sn.dat[tel][band].t[it])) / Lambda(x, y)
    print subtract(sn.dat[tel][band].t[it]), sn.dat[tel][band].t[it]
    if par['a3'] < 0.: par['a3'] = 1e-5
    return par
Exemple #3
0
def init_guess_breakout_exp(tdisc, time, mag, a2 = 1., maxt = 5.):
    """
    initial guess for breakout phase for exponential fit

    Parameters
    ----------
    tdisc: float
        discovery date
    time: `~numpy.ndarray`
        measured times
    mag: `~numpy.ndarray`
        measured magnitudes (no upper limits)

    kwargs
    ------
    a2: float, 
            initial guess for a2 parameter
    maxt: float,
        maximum time of breakout phase

    Returns
    -------
    dict with initial guesses
    """
    par = {}

    par['t0'] = tdisc

    # convert mag to flux
    y = mag2flux(mag,**ref)

    # exlcude upper limits and only use first days
    mask = time - par['t0'] < maxt

     
    itmax = np.argmax(y[mask])

    # get measurement closest to maximum
    ymax = y[mask][itmax]
    dt = time[mask][itmax] - par['t0']

    par['a2'] = a2
    
    # get initial guesses
    if dt > 10.:
        logging.warning('Estimated maximum more than 10 days after discovery!')

    par['a1'] = ymax / (1. - np.exp(-dt / par['a2']))
    return par
Exemple #4
0
def init_guess_arnett(tdisc, time, mag, delay = 10., y = 2., subtract = lambda t: 0.):
    """
    initial guess for expansion phase model with arnett

    Parameters
    ----------
    tdisc: float
        discovery date
    time: `~numpy.ndarray`
        measured times
    mag: `~numpy.ndarray`
        measured magnitudes (no upper limits)
    y: float,
       estimate for tauM (a4), where y = tauM / 2 / tauNi

    kwargs
    ------
    delay: float, 
            delay time in days when expansion should dominate.
        Flux estimated from flux corresponding to closest time
    substract: fuction pointer,
        additional flux that might contribute at time of delay

    Returns
    -------
    dict with initial guesses
    """
    par = {}

    # take discovery date as initial guess for explosion time
    par['t0'] = tdisc

    # get measurement closest to maximum
    m = np.isfinite(mag)
    it = np.argmin(np.abs(time[m] - (par['t0'] + delay)))

    # convert mag to flux
    f = mag2flux(mag[m],**ref)

    # get initial guesses
    par['a4'] = 2. * y * tauNi
    x = delay / par['a4']
    par['a3'] = (f[it] - subtract(time[it])) / Lambda(x,y)

    if par['a3'] < 0.: par['a3'] = 1e-5
    return par
Exemple #5
0
def init_guess_expansion(tdisc, time, mag, delay = 10., subtract = lambda t: 0.):
    """
    initial guess for expansion phase

    Parameters
    ----------
    tdisc: float
        discovery date
    time: `~numpy.ndarray`
        measured times
    mag: `~numpy.ndarray`
        measured magnitudes (no upper limits)

    kwargs
    ------
    delay: float, 
            delay time in days when expansion should dominate.
        Flux estimated from flux corresponding to closest time
    substract: function pointer,
        additional flux that might contribute at time of delay

    Returns
    -------
    dict with initial guesses
    """
    par = {}

    # take discovery date as initial guess for explosion time
    par['t0'] = tdisc

    # get measurement closest to maximum
    it = np.argmin(np.abs(time - (par['t0'] + delay)))

    # convert mag to flux
    y = mag2flux(mag,**ref)

    # get initial guesses
    par['a4'] = 2.
    par['a3'] = (y[it] - subtract(time[it])) / delay ** par['a4']
    if par['a3'] < 0.: par['a3'] = 1e-5
    return par
Exemple #6
0
    def __init__(self, sn, tel, bands, **kwargs):
        """
	Initialize the class

	Parameters
	----------
	sn: snlc::getlc::SNLC object,
	    SN light curve object
	tel: string,
	    name of instrument for which light curve is fitted
	bands: list,
	    list with strings with the bands included in the fit

	kwargs
	------
	tmin: float,
	    min MJD for fit
	tmax: float,
	    max MJD for fit
	model: string
	    identifier for the model. Possibilities are:
	    - "break+exp" breakout and expansion phase, expansion phase modeled as 
	    	simple quadratic expansion as in Cowen et al. (2010)
	    - "break+arnett" breakout and expansion phase, expansion phase modeled as 
	    	with function from Arnett (1982)	
	"""

        self.llhs = {}
        self.y = {}
        self.dy = {}
        self.t = {}
        self.mask = {}
        self.maxL = {}
        self.bands = bands
        self.t_first_data_point = 1e10
        # get the data and build Gaussian likelihood curves from them
        for i, b in enumerate(bands):
            if not i:
                self.llhs[b] = []
                self.t[b] = []
                self.y[b] = []
                self.dy[b] = []
                self.mask[b] = []

            # mask min, max times and ULs
            self.mask[b] = (sn.dat[tel][b].dm > 0) & (sn.dat[tel][b].t > kwargs['tmin']) & \
             (sn.dat[tel][b].t < kwargs['tmax'])
            if not np.sum(self.mask[b]):
                logging.warning(
                    'no data points remaining for {0:s} band {1:s}'.format(
                        tel, b))

            # convert magnitude to flux
            # and symmetrize errors
            self.y[b] = mag2flux(sn.dat[tel][b].m, **ref)
            self.dy[b] = np.abs(
                np.array([
                    self.y[b] -
                    mag2flux(sn.dat[tel][b].m + sn.dat[tel][b].dm, **ref),
                    mag2flux(sn.dat[tel][b].m - sn.dat[tel][b].dm, **ref) -
                    self.y[b]
                ]).mean(axis=0))

            self.t[b] = sn.dat[tel][b].t
            # find first data point
            if np.min(self.t[b][self.mask[b]]) < self.t_first_data_point:
                self.t_first_data_point = np.min(self.t[b][self.mask[b]])

            # get a likelihood curve for each data point
            self.maxL[b] = 0.
            for j, f in enumerate(self.y[b][self.mask[b]]):
                self.llhs[b].append(
                    stats.norm(loc=f, scale=(self.dy[b][self.mask[b]])[j]))
                self.maxL[b] -= self.llhs[b][-1].pdf(
                    (self.y[b][self.mask[b]])[j])

        if kwargs['model'] == 'break+exp':
            self.flux_model = lambda t, **par: breakoutphase(
                t, **par) + expansionphase(t, **par)
            self.parnames = ['t0', 'a1', 'a2', 'a3']
        elif kwargs['model'] == 'break+arnett':
            self.flux_model = lambda t, **par: breakoutphase(
                t, **par) + expansionphase_arnett(t, **par)
            self.parnames = ['t0', 'a1', 'a2', 'a3', 'a4']
        elif kwargs['model'] == 'breakexp+arnett':
            self.flux_model = lambda t, **par: breakoutexp(
                t, **par) + expansionphase_arnett(t, **par)
            self.parnames = ['t0', 'a1', 'a2', 'a3', 'a4']
        else:
            raise ValueError('Model {0[model]:s} unknown!'.format(kwargs))

        self.corr = []
        self.chi2 = kwargs['chi2']
        return
Exemple #7
0
def init_guess_breakout(sn, tel, band, a2=5., da=1., maxt=5.):
    """
    initial guess for breakout phase

    Parameters
    ----------
    sn: snlc::getlc::SNLC object,
	SN light curve object
    tel: string, 
        telescope under consideration
    band: string, 
        band under consideration

    kwargs
    ------
    a2: float, 
    	initial guess for a2 parameter
    da: float,
	increment and decrement for a2 to find root
    maxt: float,
	maximum time of breakout phase

    Returns
    -------
    dict with initial guesses
    """
    par = {}

    # discovery date
    tdisc = sn.get_dates_mjd(datetype='discover')[0]
    # first measurement
    t1 = sn.dat[tel][band].t[0]

    #    par['t0'] = 0.5 * (tdisc + t1)
    par['t0'] = t1 - 1e-2

    # convert mag to flux
    y = mag2flux(sn.dat[tel][band].m, **ref)

    # exlcude upper limits and only use first days
    mask = (sn.dat[tel][band].dm > 0.) & \
     (sn.dat[tel][band].t - par['t0'] < maxt)

    itmax = np.argmax(y[mask])

    # get measurement closest to maximum
    ymax = y[mask][itmax]
    dt = sn.dat[tel][band].t[mask][itmax] - par['t0']

    # determine a2 such that maximum flux coincides with max of function
    # the derivative = 0:
    df_dt = lambda a2, dt: (1. - a2 / 3.2 * np.sqrt(dt)) * np.exp(a2 * np.sqrt(
        dt)) - 1.
    logging.info('root finding interval: [{0},{1}] gives [{2},{3}]'.format(
        a2 - 1, a2 + 1, df_dt(a2 - da, dt), df_dt(a2 + da, dt)))
    try:
        par['a2'] = op.brentq(df_dt, a2 - da, a2 + da, args=(dt))
        logging.info('Root found at {0[a2]:.2f}.'.format(par))
    except ValueError:
        logging.warning(
            'Could not run brentq, setting a2 to {0:.2f}'.format(a2))
        par['a2'] = a2

    # get initial guesses
    if dt > 10.:
        logging.warning('Estimated maximum more than 10 days after discovery!')

    par['a1'] = ymax * np.power(dt,
                                -1.6) * (np.exp(par['a2'] * np.sqrt(dt)) - 1.)
    return par
Exemple #8
0
    def __init__(self,time,mag,dmag,tdisc,**kwargs):
        """
        Initialize the class

        Parameters
        ----------
        time: `~numpy.ndarray`
            measured times
        mag: `~numpy.ndarray`
            measured magnitudes (no upper limits)
        dmag: `~numpy.ndarray`
            uncertainties measured magnitudes (no upper limits)
        tdisc: float
            discovery date

        kwargs
        ------
        tmin: float,
            min time for fit
        tmax: float,
            max time for fit
        model: string
            identifier for the model. Possibilities are:
            - "break+expand" breakout and expansion phase, expansion phase modeled as 
                    simple quadratic expansion as in Cowen et al. (2010), modified 
                so that it can be non-quadratic
            - "break+arnett" breakout and expansion phase, expansion phase modeled as 
                    with function from Arnett (1982)        
            - "breakexp+expand" exponential breakout and expansion phase, breakout modeled 
                    with simple exponential function of Ofek et al. (2014)
            - "breakexp+arnett" breakout and expansion phase,  breakout modeled 
                    with simple exponential function of Ofek et al. (2014) and
                expansion phase modeled as with function from Arnett (1982)        
        """
        kwargs.setdefault('name','sn')
        self.name = kwargs['name']


        m = (time >= kwargs['tmin']) & (time <= kwargs['tmax'])
        self._t = time[m]
        self._y = mag2flux(mag, **ref)[m]
        self._dy = np.abs(np.array([self._y - mag2flux(mag + dmag,**ref)[m],
                    mag2flux(mag-dmag,**ref)[m] - self._y]).mean(axis = 0))

        self.t_first_data_point = tdisc
        self.__set_llhs()
        self.modelname = kwargs['model']

        self.parnames = ['t0','a1','a2']

        # Set the breakout model
        if kwargs['model'].find('break') == 0 and kwargs['model'].find('breakexp') < 0:
            self.breakout = lambda t,**par : breakoutphase(t,**par)
        elif kwargs['model'].find('breakexp') == 0:
            self.breakout = lambda t,**par : breakoutexp(t,**par)
        else:
            raise ValueError('Model {0[model]:s} unknown!'.format(kwargs))

        # Set the expansion model
        if kwargs['model'].find('expand') > 0:
            self.expansion = lambda t,**par : expansionphase(t,**par)
            self.parnames += ['a3','a4']
        elif kwargs['model'].find('arnett') > 0:
            self.expansion = lambda t,**par : expansionphase_arnett(t,**par)
            self.parnames += ['a3','a4']
        else:
            self.expansion = lambda t,**par : np.squeeze(np.zeros(t.size))

        self.flux_model = lambda t,**par : self.breakout(t,**par) + self.expansion(t,**par)

        self.corr  = []
        self.chi2 = kwargs['chi2']
        return
Exemple #9
0
def init_guess_breakout(tdisc, time, mag, a2 = 5., da = 1., maxt = 5.):
    """
    initial guess for breakout phase

    Parameters
    ----------
    tdisc: float
        discovery date
    time: `~numpy.ndarray`
        measured times
    mag: `~numpy.ndarray`
        measured magnitudes (no upper limits)

    kwargs
    ------
    a2: float, 
            initial guess for a2 parameter
    da: float,
        increment and decrement for a2 to find root
    maxt: float,
        maximum time of breakout phase

    Returns
    -------
    dict with initial guesses
    """
    par = {}

    par['t0'] = tdisc

    # convert mag to flux
    y = mag2flux(mag,**ref)

    # only use first days
    mask = time - par['t0'] < maxt

     
    itmax = np.argmax(y[mask])

    # get measurement closest to maximum
    ymax = y[mask][itmax]
    dt = time[mask][itmax] - par['t0']

    # determine a2 such that maximum flux coincides with max of function
    # the derivative = 0:
    df_dt = lambda a2,dt: (1. - a2 / 3.2 * np.sqrt(dt) ) * np.exp(a2 * np.sqrt(dt)) - 1.
    logging.info('root finding interval: [{0},{1}] gives [{2},{3}]'.format(a2 - 1, a2 + 1,
                        df_dt(a2 - da,dt), df_dt(a2 + da,dt)))
    try:

        res =  op.brentq(df_dt, a2 - da , a2 + da, args = (dt))
        if res > 1e-4:
            par['a2'] = res
            logging.info('Root found at {0[a2]:.2f}.'.format(par))
            else:
            par['a2'] = a2
    except ValueError:
        logging.warning('Could not run brentq, setting a2 to {0:.2f}'.format(a2))
        par['a2'] = a2

    
    # get initial guesses
    if dt > 10.:
        logging.warning('Estimated maximum more than 10 days after discovery!')

    par['a1'] = ymax * np.power(dt,-1.6) * (np.exp(par['a2'] * np.sqrt(dt)) - 1.)
    return par