Exemple #1
0
def plot_lira(t, t2, t_maxes, BV, eBV, BV2, tmin, tmax, c):

    p = pygplot.Plot(device='9/XS',
                     font=2,
                     fsize=1.5,
                     xlabel='Epoch (Vmax)',
                     ylabel='B-V')
    p.point(t - t_maxes[0], BV, symbol=4, fill=1)
    p.error(t - t_maxes[0], BV, dy1=eBV, length=0)
    p.point(t2,
            BV2,
            symbol=4,
            fill=1,
            fillcolor='red',
            label='B-V (deredshifted)')
    p.line([tmin, tmax],
           [0.732 - 0.0095 * (tmin - 55), 0.732 - 0.0095 * (tmax - 55)],
           color='blue',
           label='Lira Law')
    p.line([tmin, tmax],
           [c[0] + c[1] * (tmin - 55), c[0] + c[1] * (tmax - 55)],
           color='red',
           label='Fit')
    p.legend(position='ur', fsize=1)
    p.plot()
    p.close()
Exemple #2
0
def plot_mangled_SED(x, y, key, inst):

    p = pygplot.Plot(device='14/XS',
                     font=1.5,
                     fsize=2,
                     xlabel='Wavelength (Angstroms)',
                     ylabel='Flux')
    band = inst.filter
    self = inst.inst
    id = argmin(power(x - self.data[band].t, 2) + power(y - self.ks[band], 2))
    day = int(self.data[band].t[id])
    wave, flux = kcorr.get_SED(day, version='H3')
    p.line(wave, flux, label='Original SED')

    if band in self.ks_mopts:
        man_flux = mangle_spectrum.apply_mangle(wave, flux,
                                                **self.ks_mopts[band][id])
        p.line(wave, man_flux, label='Mangled SED', color='007700')
    f1 = fset[band]
    f2 = fset[self.restbands[band]]
    p.line(f1.wave, f1.resp / f1.resp.max() * flux.max(), color='red')
    p.line(f2.wave * (1 + self.z),
           f2.resp / f2.resp.max() * flux.max(),
           color='blue')

    p.legend(fsize=1.5)
    p.xrange = [fset[band].wave.min() * 0.9, fset[band].wave.max() * 1.1]
    p.plot()
    p.close()
Exemple #3
0
def plot_filters(self, bands=None, day=0):
    '''Plot the filter responses, both the observed ones and the restbands
   defined in the sn instance in the rest frame of the SN.  If bands is specified,
   only plot those.  Specify which SED to plot using day.'''
    p = pygplot.Plot(xlabel='Wavelength (\A)',
                     ylabel='relative flux',
                     title='Filter responses + %s SED (day %d)' %
                     (self.k_version, day),
                     device="11/XWIN")

    # first, get the SED:
    sed_wav, sed_flux = kcorr.get_SED(day, self.k_version)
    # normalize:
    sed_flux = sed_flux / maximum.reduce(sed_flux)
    p.sed_line = p.line(sed_wav * (1 + self.z), sed_flux, autorange=0)
    p.current_day = day
    p.version = self.k_version
    p.z = self.z

    # Next, for each filter, plot the response and rest band closest to it:
    if bands is None: bands = list(self.data.keys())
    if type(bands) is bytes:
        bands = [bands]

    for band in bands:
        f1 = fset[band]
        f2 = fset[self.restbands[band]]
        maxresp = maximum.reduce(f1.resp)
        max_wave = f1.wave[argmax(f1.resp)]
        p.line(f1.wave, f1.resp / maxresp, color='blue')
        p.label(max_wave, 1.05, band, color='blue')
        maxresp = maximum.reduce(f2.resp)
        max_wave = f2.wave[argmax(f2.resp)] * (1 + self.z)
        p.line(f2.wave * (1 + self.z), f2.resp / maxresp, color='red')
        p.label(max_wave, 1.05, self.restbands[band], color='red')

    p.plot()
    p.interact(bindings={'D': advance_day, 'd': advance_day})
    pygplot.ppgplot.pgask(0)
    p.close()
Exemple #4
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)
Exemple #5
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)
Exemple #6
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)
Exemple #7
0
def matchum(file1,
            file2,
            tol=10,
            perr=4,
            aerr=1.0,
            nmax=40,
            im_masks1=[],
            im_masks2=[],
            debug=0,
            domags=0,
            xrange=None,
            yrange=None,
            sigma=4,
            aoffset=0):
    '''Take the output of two sextractor runs and match up the objects with
   each other (find out which objects in the first file match up with
   objects in the second file.  The routine considers a 'match' to be any 
   two objects that are closer than tol pixels (after applying the shift).  
   Returns a 6-tuple:  (x1,y1,x2,y2,o1,o2).  o1 and o2 are the ojbects
   numbers such that o1[i] in file 1 corresponds to o2[i] in file 2.'''
    NA = num.NewAxis

    sexdata1 = readsex(file1)
    sexdata2 = readsex(file2)

    # Use the readsex data to get arrays of the (x,y) positions
    x1 = num.asarray(sexdata1[0]['X_IMAGE'])
    y1 = num.asarray(sexdata1[0]['Y_IMAGE'])
    x2 = num.asarray(sexdata2[0]['X_IMAGE'])
    y2 = num.asarray(sexdata2[0]['Y_IMAGE'])
    m1 = num.asarray(sexdata1[0]['MAG_BEST'])
    m2 = num.asarray(sexdata2[0]['MAG_BEST'])
    o1 = num.asarray(sexdata1[0]['NUMBER'])
    o2 = num.asarray(sexdata2[0]['NUMBER'])
    f1 = num.asarray(sexdata1[0]['FLAGS'])
    f2 = num.asarray(sexdata2[0]['FLAGS'])

    # First, make a cut on the flags:
    gids = num.where(f1 < 4)
    x1 = x1[gids]
    y1 = y1[gids]
    m1 = m1[gids]
    o1 = o1[gids]
    gids = num.where(f2 < 4)
    x2 = x2[gids]
    y2 = y2[gids]
    m2 = m2[gids]
    o2 = o2[gids]

    # next, if there is a range to use:
    if xrange is not None and yrange is not None:
        cond = num.greater(x1, xrange[0])*num.less(x1,xrange[1])*\
              num.greater(y1, yrange[0])*num.less(y1,yrange[1])
        gids = num.where(cond)
        x1 = x1[gids]
        y1 = y1[gids]
        m1 = m1[gids]
        o1 = o1[gids]
        cond = num.greater(x2, xrange[0])*num.less(x2,xrange[1])*\
              num.greater(y2, yrange[0])*num.less(y2,yrange[1])
        gids = num.where(cond)
        x2 = x2[gids]
        y2 = y2[gids]
        m2 = m2[gids]
        o2 = o2[gids]

    # Use the user masks
    for m in im_masks1:
        print "applying mask (%d,%d,%d,%d)" % tuple(m)
        condx = num.less(x1, m[0]) + num.greater(x1, m[1])
        condy = num.less(y1, m[2]) + num.greater(y1, m[3])
        gids = num.where(condx + condy)
        x1 = x1[gids]
        y1 = y1[gids]
        m1 = m1[gids]
        o1 = o1[gids]

    for m in im_masks2:
        print "applying mask (%d,%d,%d,%d)" % tuple(m)
        condx = num.less(x2, m[0]) + num.greater(x2, m[1])
        condy = num.less(y2, m[2]) + num.greater(y2, m[3])
        gids = num.where(condx + condy)
        x2 = x2[gids]
        y2 = y2[gids]
        m2 = m2[gids]
        o2 = o2[gids]

    if nmax:
        if len(x1) > nmax:
            ids = num.argsort(m1)[0:nmax]
            x1 = x1[ids]
            y1 = y1[ids]
            m1 = m1[ids]
            o1 = o1[ids]
        if len(x2) > nmax:
            ids = num.argsort(m2)[0:nmax]
            x2 = x2[ids]
            y2 = y2[ids]
            m2 = m2[ids]
            o2 = o2[ids]
    if debug:
        print "objects in frame 1:"
        print o1
        print "objects in frame 2:"
        print o2
        mp = pygplot.MPlot(2, 1, device='/XWIN')
        p = pygplot.Plot()
        p.point(x1, y1)
        [p.label(x1[i], y1[i], "%d" % o1[i]) for i in range(len(x1))]
        mp.add(p)
        p = pygplot.Plot()
        p.point(x2, y2)
        [p.label(x2[i], y2[i], "%d" % o2[i]) for i in range(len(x2))]
        mp.add(p)
        mp.plot()
        mp.close()

    # Now, we make 2-D arrays of all the differences in x and y between each pair
    #  of objects.  e.g., dx1[n,m] is the delta-x between object n and m in file 1 and
    #  dy2[n,m] is the y-distance between object n and m in file 2.
    dx1 = x1[NA, :] - x1[:, NA]
    dx2 = x2[NA, :] - x2[:, NA]
    dy1 = y1[NA, :] - y1[:, NA]
    dy2 = y2[NA, :] - y2[:, NA]
    # Same, but with angles
    da1 = num.arctan2(dy1, dx1) * 180 / num.pi
    da2 = num.arctan2(dy2, dx2) * 180 / num.pi
    # Same, but with absolute distances
    ds1 = num.sqrt(num.power(dx1, 2) + num.power(dy1, 2))
    ds2 = num.sqrt(num.power(dx2, 2) + num.power(dy2, 2))

    # Here's the real magic:  this is a matrix of matrices (4-D).  Consider 4 objects:
    #  objects i and j in file 1 and objects m and n in file 2.  dx[i,j,m,n] is the
    #  difference between delta-xs for objects i,j in file 1 and m,n in file 2.  If object
    #  i corresponds to object m and object j corresponds to object n, this should be a small
    #  number, irregardless of an overall shift in coordinate systems between file 1 and 2.
    dx = dx1[::, ::, NA, NA] - dx2[NA, NA, ::, ::]
    dy = dy1[::, ::, NA, NA] - dy2[NA, NA, ::, ::]
    da = da1[::, ::, NA, NA] - da2[NA, NA, ::, ::] + aoffset
    ds = ds1[::, ::, NA, NA] - ds2[NA, NA, ::, ::]
    # pick out close pairs.
    #use = num.less(dy,perr)*num.less(dx,perr)*num.less(num.abs(da),aerr)
    use = num.less(ds, perr) * num.less(num.abs(da), aerr)
    use = use.astype(num.Int32)

    #use = num.less(num.abs(da),perr)
    suse = num.add.reduce(num.add.reduce(use, 3), 1)
    print suse[0]

    guse = num.greater(suse, suse.flat.max() / 2)
    i = [j for j in range(x1.shape[0]) if num.sum(guse[j])]
    m = [num.argmax(guse[j]) for j in range(x1.shape[0]) if num.sum(guse[j])]
    xx0, yy0, oo0, mm0 = num.take([x1, y1, o1, m1], i, 1)
    xx1, yy1, oo1, mm1 = num.take([x2, y2, o2, m2], m, 1)
    if debug:
        mp = pygplot.MPlot(2, 1, device='/XWIN')
        p = pygplot.Plot()
        p.point(xx0, yy0)
        [p.label(xx0[i], yy0[i], "%d" % oo0[i]) for i in range(len(xx0))]
        mp.add(p)
        p = pygplot.Plot()
        p.point(xx1, yy1)
        [p.label(xx1[i], yy1[i], "%d" % oo1[i]) for i in range(len(xx1))]
        mp.add(p)
        mp.plot()
        mp.close()
    xshift, xscat = stats.bwt(xx0 - xx1)
    xscat = max([1.0, xscat])
    yshift, yscat = stats.bwt(yy0 - yy1)
    yscat = max([1.0, yscat])
    mshift, mscat = stats.bwt(mm0 - mm1)
    print "xscat = ", xscat
    print "yscat = ", yscat
    print "xshift = ", xshift
    print "yshift = ", yshift
    print "mshift = ", mshift
    print "mscat = ", mscat
    keep = num.less(num.abs(xx0-xx1-xshift),sigma*xscat)*\
          num.less(num.abs(yy0-yy1-yshift),sigma*yscat)
    # This is a list of x,y,object# in each file.
    xx0, yy0, oo0, xx1, yy1, oo1 = num.compress(keep,
                                                [xx0, yy0, oo0, xx1, yy1, oo1],
                                                1)

    if debug:
        print file1, oo0
        print file2, oo1
        mp = pygplot.MPlot(2, 1, device='temp.ps/CPS')
        p1 = pygplot.Plot()
        p1.point(xx0, yy0, symbol=25, color='red')
        for i in range(len(xx0)):
            p1.label(xx0[i], yy0[i], " %d" % oo0[i], color='red')
        mp.add(p1)
        p2 = pygplot.Plot()
        p2.point(xx1, yy1, symbol=25, color='green')
        for i in range(len(xx1)):
            p2.label(xx1[i], yy1[i], " %d" % oo1[i], color='green')
        mp.add(p2)
        mp.plot()
        mp.close()

    if domags:
        return (xx0, yy0, mm0, xx1, yy1, mm1, mshift, mscat, oo0, oo1)
    else:
        return (xx0, yy0, xx1, yy1, oo0, oo1)