Ejemplo n.º 1
0
def plot_lc(self,
            device='/XSERVE',
            interactive=0,
            epoch=1,
            flux=0,
            gloes=0,
            symbol=4):
    '''Plot this light-curve.  You can specify a PGPLOT device, the default is an X
   server.  If interactive=1, basic pygplot keybindings are available.  If flux=1,
   plot in flux space.  If epoch=1, plot time relative to Tmax.  If gloes=1, 
   use GLoEs to smooth the data and produce a model.  You can specify the
   symbol to plot with 'symbol'.'''
    if flux:
        flipaxis = 0
    else:
        flipaxis = 1
    p = pygplot.Plot(flipyaxis=flipaxis,
                     title='%s %s lightcurve' % (self.parent.name, self.band),
                     xlabel='Epoch (days)',
                     ylabel='mag',
                     font=2,
                     leftpad=0.5)
    p.lc_inst = self
    p.epoch = epoch
    p.flux = flux
    if self.parent.Tmax is None:
        Tmax = 0
    else:
        Tmax = self.parent.Tmax

    if gloes or self.model_type is not None or self.band in self.parent.model._fbands:
        self.mp = pygplot.Panel(device=device,
                                llcs=[(0.0, 0.2), (0.0, 0.0)],
                                urcs=[(1.0, 1.0), (1.0, 0.2)],
                                justs=[12, 13])
        p2 = pygplot.Plot(flipyaxis=flipaxis,
                          xlabel='Epoch (days)',
                          font=2,
                          ylabel='residuals',
                          leftpad=0.5)
        p2.lc_inst = self
    else:
        self.mp = pygplot.Panel(1, 1, device=device)
    self.mp.add(p)
    if gloes or self.model_type is not None or self.band in self.parent.model._fbands:
        self.mp.add(p2)
    if flux:
        y = power(10, -0.4 * (self.mag - self.filter.zp))
        ey = y * self.e_mag / 1.0857
    else:
        y = self.mag
        ey = self.e_mag
    p.point(self.MJD - epoch * Tmax, y, symbol=symbol)
    p.error(self.MJD - epoch * Tmax, y, dy1=ey)

    # Order of preference:  plot models, else plot splines, else plot
    #  nothing unless we explicitly ask for gloess.
    if self.band in self.parent.model._fbands:
        t = arange(-10, 70, 1.0) + Tmax
        m, em, mask = self.parent.model(self.band, t)
        m_m, m_em, m_mask = self.parent.model(self.band, self.MJD)
        x = self.MJD[self.mask * m_mask]
        if flux and self.parent.model.model_in_mags:
            p.line(t[mask] - epoch * Tmax,
                   power(10, -0.4 * (m - self.filter.zp)))
            y = compress(self.mask * m_mask,
                         self.flux - power(10, -0.4 * (m_m - self.filter.zp)))
            dy = self.e_flux[self.mask * m_mask]
        elif not flux and not self.parent.model.model_in_mags:
            p.line(t[mask] - epoch * Tmax,
                   -2.5 * log10(m[mask]) + self.filter.zp)
            y = compress(self.mask * m_mask,
                         self.mag + 2.5 * log10(m_m) + self.filter.zp)
            dy = self.e_mag[self.mask * m_mask]
        elif flux:
            p.line(t[mask] - epoch * Tmax, m[mask])
            y = self.flux[self.mask * m_mask] - m_m[self.mask * m_mask]
            dy = self.e_flux[self.mask * m_mask]
        else:
            p.line(t[mask] - epoch * Tmax, m[mask])
            y = self.mag[self.mask * m_mask] - m_m[self.mask * m_mask]
            dy = self.e_mag[self.mask * m_mask]

        p2.point(x - epoch * Tmax, y, symbol=symbol)
        p2.error(x - epoch * Tmax, y, dy1=dy)
        p2.line([t[0] - epoch * Tmax, t[-1] - epoch * Tmax], [0, 0])

    elif gloes or self.model_type is not None:
        if self.tmin is not None and self.tmax is not None:
            t = arange(self.tmin, self.tmax + 1, 1.0)
        else:
            t = arange(self.MJD[0], self.MJD[-1] + 1, 1.0)
        self._t = t
        self._epoch = epoch
        m, mask = self.eval(t, t_tol=None)
        m_model, m_mask = self.eval(self.MJD, t_tol=None)
        if flux:
            p.line(compress(mask, t - epoch * Tmax),
                   compress(mask, power(10, -0.4 * (m - self.filter.zp))))
            if self.tck is not None:
                p.point(self.tck[0] - epoch*Tmax, power(10, -0.4*(self.eval(self.tck[0], t_tol=None)[0] \
                   - self.filter.zp)), color='red', symbol=4)
            x = compress(self.mask * m_mask, self.MJD)
            y = compress(
                self.mask * m_mask,
                self.flux - power(10, -0.4 * (m_model - self.filter.zp)))
            dy = compress(self.mask * m_mask, self.e_flux)
            p2.point(x - epoch * Tmax, y, symbol=symbol)
            p2.error(x - epoch * Tmax, y, dy1=dy)
        else:
            p.line(compress(mask, t - epoch * Tmax), compress(mask, m))
            if self.tck is not None:
                p.point(self.tck[0] - epoch * Tmax,
                        self.eval(self.tck[0], t_tol=None)[0],
                        color='red',
                        symbol=4)
            x = compress(self.mask * m_mask, self.MJD)
            y = compress(self.mask * m_mask, self.mag - m_model)
            p2.point(x - epoch * Tmax, y, symbol=symbol)
            dy = compress(self.mask * m_mask, self.e_mag)
            p2.error(x - epoch * Tmax, y, dy1=dy)
        if self.tck is not None:
            p2.line(
                array([self.tck[0][0], self.tck[0][-1]]) - epoch * Tmax,
                [0, 0])
        else:
            p2.line(array([self.MJD[0], self.MJD[-1]]) - epoch * Tmax, [0, 0])
        # useful stats:
        if self.tck is not None:
            p.label(0.5, 1.03, 'Np = %d  Nk = %d  s = %.1f r-chi-sq = %.2f' % \
               (len(self.mag), len(self.tck[0]), self.s, self.rchisq),
               reference='relative', fsize=1, just=0.5)
        else:
            if self.line.N is not None: N = self.line.N
            else: N = -1
            if self.line.sigma is not None: sigma = self.line.sigma
            else: sigma = -1
            p.label(0.5, 1.03, 'N = %d   sigma = %.1f   r-chi-sq = %.2f' % \
                  (N,sigma,self.line.chisq()), reference='relative', fsize=1, just=0.5)

    self.mp.plot()
    if len(self.mp.plots) == 2:
        self.mp.plots[1].xrange = [
            self.mp.plots[0].xmin, self.mp.plots[0].xmax
        ]
        self.mp.replot()
    if interactive:
        self.mp.interact(
            bindings={
                'a': add_knot,
                'd': delete_knot,
                'm': move_knot,
                's': change_s,
                'S': change_s,
                'n': change_N,
                'N': change_N,
                'x': xrange_select,
                'b': box_range_select
            })
    self.mp.close()
    return (self.mp)
Ejemplo n.º 2
0
def plot_kcorrs(self, device='13/XW', colors=None, symbols=None):
    '''Plot the k-corrections, both mangled and un-mangled.'''
    # See  what filters we're going to use:
    bands = list(self.ks.keys())
    if len(bands) == 0:
        return

    if colors is None: colors = default_colors
    if symbols is None: symbols = default_symbols

    eff_wavs = []
    for filter in bands:
        eff_wavs.append(fset[filter].ave_wave)
    eff_wavs = asarray(eff_wavs)
    ids = argsort(eff_wavs)
    bands = [bands[i] for i in ids]
    minx = Inf
    maxx = -Inf
    for b in bands:
        if b not in colors: colors[b] = 1
        if b not in symbols: symbols[b] = 4
        minx = min(minx, self.data[b].t.min())
        maxx = max(maxx, self.data[b].t.max())
    n_plots = len(bands)
    cols = int(round(sqrt(n_plots)))
    rows = (n_plots / cols)
    if n_plots % cols: rows += 1
    p = pygplot.Panel(1, n_plots, device=device, aspect=1.0 / 6 * n_plots)

    for b in bands:
        x = self.data[b].MJD - self.Tmax
        days = arange(int(x[0]), int(x[-1]), 1)
        rest_days = days / (1 + self.z) / self.ks_s
        k, k_m = list(
            map(
                array,
                kcorr.kcorr(rest_days.tolist(),
                            self.restbands[b],
                            b,
                            self.z,
                            self.EBVgal,
                            0.0,
                            version=self.k_version)))
        k_m = equal(k_m, 1)
        pp = pygplot.Plot(fsize=1,
                          font=2,
                          xlabel='Epoch (days)',
                          leftpad=0.1,
                          rotylab=1,
                          xrange=[minx, maxx])
        pp.filter = b
        pp.inst = self
        p.add(pp)
        pp.line(days[k_m], k[k_m], color=colors[b])
        pp.point(x[self.ks_mask[b]],
                 self.ks[b][self.ks_mask[b]],
                 symbol=symbols[b],
                 color=colors[b],
                 fillcolor=colors[b],
                 fsize=2)
        pp.label(0.9, 0.9, b, just=1, vjust=1, reference='relative')

    p.plots[n_plots / 2].ylabel = 'K-correction'
    p.plot()
    p.interact(bindings={'A': plot_mangled_SED})
    p.close()
    return (p)
Ejemplo n.º 3
0
def plot_sn(self,
            xrange=None,
            yrange=None,
            device=None,
            title=None,
            interactive=0,
            single=0,
            dm=1,
            fsize=1.0,
            linewidth=3,
            symbols=None,
            colors=None,
            relative=0,
            legend=1,
            mask=1,
            label_bad=0,
            flux=0,
            epoch=0,
            **pargs):
    '''Plot out the supernova data in a nice format.  There are several 
   options:
      - xrange,yrange:  specify the ranges to plot as lists [xmin,xmax], 
        [ymin,ymax]
      - title:  optional title
      - device:  which device to use.  Useful for output to file
      - interactive:  allows for an interactive plot.
      - single:  plot out as a single (rather than panelled) plot?
      - dm:  offset in magnitudes between the lightcurves (for single plots)
      - fsize:  override the font size used to plot the graphs
      - linewidth:  override the line width
      - symbols:  dictionary of symbols, indexed by band name.
      - colors:  dictionary of colors to use, indexed by band name.
      - relative:  plot only relative magnitudes (normalized to zero)?
      - legend:  do we plot the legend?
      - mask:  Omit plotting masked out data?
      - label_bad:  label the masked data with red x's?
   '''

    if not xrange: xrange = self.xrange
    if not yrange: yrange = self.yrange
    if not symbols: symbols = default_symbols
    if not colors: colors = default_colors
    if device is None: device = self.device
    if fsize is None: fsize = 1.0
    if linewidth is None: linewidth = 3

    # See  what filters we're going to use:
    if self.filter_order is not None:
        bands = self.filter_order
    else:
        bands = list(self.data.keys())
        if not single:
            eff_wavs = []
            for filter in bands:
                eff_wavs.append(fset[filter].ave_wave)
            eff_wavs = asarray(eff_wavs)
            ids = argsort(eff_wavs)
            self.filter_order = [bands[i] for i in ids]
        else:
            mins = []
            for filter in bands:
                if getattr(self.data[filter], 'model', None) is not None:
                    mins.append(min(self.data[filter].model))
                else:
                    mins.append(min(self.data[filter].mag))
            mins = asarray(mins)
            ids = argsort(mins)
            self.filter_order = [bands[i] for i in ids]
        bands = self.filter_order

    for b in bands:
        if b not in colors: colors[b] = 1
        if b not in symbols: symbols[b] = 4
    if relative:
        if self.data[bands[0]].model is not None:
            rel_off = min(self.data[bands[0]].model)
        else:
            rel_off = min(self.data[bands[0]].mag)
    else:
        rel_off = 0

    n_plots = len(bands)
    # SHould we plot the y-axis upside-down?
    if not flux:
        flip = 1
        ylabel = 'magnitude'
    else:
        flip = 0
        ylabel = 'relative flux'
    if not single:
        cols = int(round(sqrt(n_plots)))
        rows = (n_plots / cols)
        if n_plots % cols: rows += 1
        self.p = pygplot.Panel(cols,
                               rows,
                               device='/NULL',
                               aspect=1.0 * rows / cols)
    else:
        self.p = pygplot.Plot(device='/NULL',
                              title=title,
                              flipyaxis=flip,
                              xrange=xrange,
                              yrange=yrange,
                              fsize=fsize,
                              linewidth=linewidth,
                              width=linewidth,
                              xlabel='Epoch (days)',
                              ylabel=ylabel,
                              **pargs)

    i = 0
    for filter in bands:
        if not single:
            pp = pygplot.Plot(device='/NULL',
                              aspect=1.0,
                              flipyaxis=flip,
                              xrange=xrange,
                              yrange=yrange,
                              linewidth=linewidth,
                              font=2,
                              fsize=fsize,
                              width=linewidth,
                              **pargs)
            # make a reference to the lightcruve we are plotting.
            pp.lc = self.data[filter]
        else:
            pp = self.p
        if not i and title is None:
            label = self.name + " " + filter
        else:
            label = filter
        if not single:
            pp.label(0.8,
                     0.9,
                     label,
                     reference='relative',
                     color=colors[filter],
                     just=1,
                     fsize=fsize,
                     vjust=1)
        if mask:
            x = self.data[filter].MJD[self.data[filter].mask]
            if not flux:
                y = self.data[filter].mag[self.data[filter].mask] + \
                      single*i*dm - relative*rel_off
                ey = self.data[filter].e_mag[self.data[filter].mask]
            else:
                y = self.data[filter].flux[self.data[filter].mask]* \
                      power(10, -0.4*(single*i*dm-relative*rel_off))
                ey = self.data[filter].e_flux[self.data[filter].mask]
        else:
            x = self.data[filter].MJD
            if not flux:
                y = self.data[filter].mag + single * i * dm - relative * rel_off
                ey = self.data[filter].e_mag
            else:
                y = self.data[filter].flux* \
                      power(10, -0.4*(single*i*dm-relative*rel_off))
                ey = self.data[filter].e_flux

        # Make the PANIC data stand out
        #if filter=='Yc' or filter == 'Jc':
        #   size = fsize + 2
        #else:
        #   size = fsize + 1
        if self.Tmax is None:
            Tmax = 0
        else:
            Tmax = self.Tmax
        pp.point(x - Tmax * epoch,
                 y,
                 symbol=symbols[filter],
                 fill=1,
                 fillcolor=colors[filter],
                 size=fsize + 1,
                 label=filter + '+' + str(i * dm))
        pp.error(x - Tmax * epoch, y, dy1=ey, length=0, order=1000)
        if label_bad:
            gids = equal(self.data[filter].mask, 0)
            if sometrue(gids):
                x = self.data[filter].MJD[gids] - Tmax * epoch
                if not flux:
                    y = self.data[filter].mag[gids] + \
                          single*i*dm - relative*rel_off
                else:
                    y = self.data[filter].flux[gids]* \
                          power(10, -0.4*(single*i*dm-relative*rel_off))
                pp.point(x, y, symbol=5, color='red', size=4.0)

        # Now check to see if there is a model to plot:
        if self.model.Tmax is not None and filter in self.model._fbands:
            t = arange(-10, 70, 1.0) + self.Tmax
            mag, err, gids = self.model(filter, t)
            if not flux:
                y = mag + i * single * dm - relative * rel_off
            else:
                zp = fset[filter].zp
                y = power(10, -0.4*(mag - zp + i*single*dm - \
                                    relative*rel_off))
            pp.line(compress(gids, t - self.Tmax * epoch),
                    compress(gids, y),
                    color=colors[filter])
        elif self.data[filter].tck is not None:
            tck = self.data[filter].tck
            t = arange(tck[0][0], tck[0][-1], 1.0)
            mag, gids = self.data[filter].eval(t, t_tol=-1)
            if not flux:
                y = mag + i * single * dm - relative * rel_off
            else:
                zp = fset[filter].zp
                y = power(10, -0.4*(mag - zp + i*single*dm- \
                                    relative*rel_off))
            if self.Tmax is None:
                Tmax = 0
            else:
                Tmax = self.Tmax
            pp.line(compress(gids, t - Tmax * epoch),
                    compress(gids, y),
                    color=colors[filter])
        i = i + 1

        if not single:
            self.p.add(pp)
        else:
            if legend: self.p.legend(position='lr', fsize=1.5, bbox=(0, 0))
            self.p.label(0.05, 0.05, self.name, reference='relative')

    self.p.plot()

    if self.xrange is None and not single:
        xmin = self.p.plots[0].xmin
        xmax = self.p.plots[0].xmax
        for plot in self.p.plots[1:]:
            xmin = min(plot.xmin, xmin)
            xmax = max(plot.xmax, xmax)
        for plot in self.p.plots:
            plot.xrange = [xmin, xmax]

    if self.yrange is None and not single:
        ymin = self.p.plots[0].ymin
        ymax = self.p.plots[0].ymax
        for plot in self.p.plots[1:]:
            if not flux:
                ymin = max(plot.ymin, ymin)
                ymax = min(plot.ymax, ymax)
            else:
                ymin = min(plot.ymin, ymin)
                ymax = max(plot.ymax, ymax)
        for plot in self.p.plots:
            plot.yrange = [ymin, ymax]

    self.p.close()
    self.p.device = device
    self.p.plot()
    if interactive: self.p.interact()
    self.p.close()
    return (self.p)