def errVsRadius(root, epoch):
    # Get the star set info
    s = starset.StarSet(root)

    x = s.getArray('x')
    y = s.getArray('y')

    xerr = s.getArrayFromEpoch(epoch, 'xerr_a')
    yerr = s.getArrayFromEpoch(epoch, 'yerr_a')

    idx = (np.where(xerr > 0))[0]

    x = x[idx]
    y = y[idx]
    xerr = xerr[idx] * 1000.0
    yerr = yerr[idx] * 1000.0

    r = np.hypot(x, y)

    p.clf()
    p.semilogy(r, xerr, 'bx')
    p.semilogy(r, yerr, 'r+')
    p.axis([0, 5, 0.05, 5])

    p.xlabel('Radius (arcsec)')
    p.ylabel('Alignment Error (mas)')

    p.title('Epoch #%d:  %8.3f' % (epoch, s.stars[0].years[epoch]))
    p.savefig('plots/alignErrVsRadius.png')
def printLabelInfo(alignRoot, polyRoot, starName):
    # Now read in the align stuff
    s = starset.StarSet(alignRoot)
    s.loadPolyfit(polyRoot, accel=0)
    mag = s.getArray('mag')
    name = np.array(s.getArray('name'))
    x0 = s.getArray('fitXv.p') * -1.0
    y0 = s.getArray('fitYv.p')
    x0err = s.getArray('fitXv.perr')
    y0err = s.getArray('fitYv.perr')
    vx = s.getArray('fitXv.v') * -1.0
    vy = s.getArray('fitYv.v')
    vxerr = s.getArray('fitXv.verr')
    vyerr = s.getArray('fitYv.verr')
    t0x = s.getArray('fitXv.t0')
    t0y = s.getArray('fitYv.t0')
    r = np.hypot(x0, y0)

    # Fix x0err, y0err to some minimum value
    idx = np.where(x0err < 0.0001)[0]
    x0err[idx] = 0.0001
    idx = np.where(y0err < 0.0001)[0]
    y0err[idx] = 0.0001

    idx = np.where(name == starName)[0]

    if len(idx) > 0:
        rr = idx[0]
        print '%-11s  %4.1f    %6.3f  %6.3f  %7.4f %7.4f  %8.3f %8.3f  %7.3f  %7.3f   %8.3f    1   %5.3f' % \
              (name[rr], mag[rr], x0[rr], y0[rr], x0err[rr],
               y0err[rr], vx[rr]*10**3, vy[rr]*10**3,
               vxerr[rr]*10**3, vyerr[rr]*10**3, t0x[rr], r[rr])
    else:
        print 'Could not find star %s' % starName
def plot2d(root, epoch):
    s = starset.StarSet(root)

    x = s.getArray('x')
    y = s.getArray('y')
    xerr = s.getArrayFromEpoch(epoch, 'xerr_a')
    yerr = s.getArrayFromEpoch(epoch, 'yerr_a')

    idx = (np.where(xerr > 0))[0]
    x = x[idx]
    y = y[idx]
    xerr = xerr[idx] * 1000.0
    yerr = yerr[idx] * 1000.0

    p.clf()
    #p.quiver([x], [y], [xerr], [yerr], 0.4)
    scale = 3.0e2
    p.scatter(x, y, xerr * scale, c='b', marker='o', alpha=0.5)
    p.scatter(x, y, yerr * scale, c='r', marker='s', alpha=0.5)
    p.scatter([-3.5], [-3.5], 0.5 * scale, c='k', marker='s')
    p.text(-3.1, -3.6, '0.5 mas')

    p.xlabel('X')
    p.ylabel('Y')
    p.title('Epoch #%d:  %8.3f' % (epoch, s.stars[0].years[epoch]))
    p.savefig('plot/salignErr2D.png')
def plotDegreesOfFreedom(root='./',
                         align='align/align_d_rms_t',
                         poly='polyfit_d_points/fit',
                         accel=False,
                         youngOnly=False):

    s = starset.StarSet(root + align)
    s.loadPolyfit(root + poly, arcsec=1, accel=accel)

    if (youngOnly):
        s.onlyYoungDisk()

    if (accel):
        dof = s.getArray('fitXa.dof')
    else:
        dof = s.getArray('fitXv.dof')

    cnt = s.getArray('velCnt')

    dofBins = np.arange(0, cnt.max() + 1)

    py.clf()
    py.hist(dof, bins=dofBins, alpha=0.6)
    py.xlabel('Degrees of Freedom')
    py.ylabel('Number of Stars')
    py.title('%d stars in %d-%d epochs' % (len(cnt), cnt.min(), cnt.max()))

    py.savefig(root + 'plots/hist_degrees_of_freedom.png')
Beispiel #5
0
def go(epoch, limMag=15):
    root = '/u/ghezgroup/data/gc/' + epoch + '/clean/kp/starfinder/align/'

    aln_list = root + 'align_kp_0.0.list'
    #frameList = asciidata.open(aln_list)
    f_list = open(aln_list)
    files = []

    for line in f_list:
        _line = line.split()
        fileParts = _line[0].split('/')
        files.append(fileParts[-1])

    files = files[1:]
    #frames = frameList[0].tonumarray()
    s = starset.StarSet(root + 'align_kp_0.0')

    numstars = asciidata.open(root + 'align_kp_0.0.mag').nrows
    numepochs = asciidata.open(root + 'align_kp_0.0.mag').ncols - 5

    fluxFile = root + '/sgra_all.mag'
    brtFile = root + '/sgra_brt.mag'
    dimFile = root + '/sgra_dim.mag'

    _sgraAll = open(fluxFile, 'w')
    _sgraBrt = open(brtFile, 'w')
    _sgraDim = open(dimFile, 'w')

    _sgraAll.write('#Frame' + '                   Mag ' + '    Flux(mJy) ' +
                   '\n')
    _sgraBrt.write('#Frame' + '                   Mag ' + '    Flux(mJy) ' +
                   '\n')
    _sgraDim.write('#Frame' + '                   Mag ' + '    Flux(mJy) ' +
                   '\n')

    # Find index for Sgr A* in the mag file
    for x in range(numstars):
        if (s.stars[x].name == 'SgrA'):
            sgra_idx = x

    # Loop through epochs and print frame, mags, & fluxes (in mJy)
    for i in range(numepochs):
        mag = s.stars[sgra_idx].e[i].mag
        flux = 655000. * 10**(-0.4 * mag)

        #frame = frames[i]
        frame = files[i]

        _sgraAll.write('%5s % 5.3f %7.2f\n' % (frame, mag, flux))

        if (mag < limMag):
            _sgraBrt.write('%5s % 5.3f %7.2f\n' % (frame, mag, flux))
        else:
            _sgraDim.write('%5s % 5.3f %7.2f\n' % (frame, mag, flux))

    _sgraAll.close()
    _sgraBrt.close()
    _sgraDim.close()
    def process_align_output(alignRoot):
        """
        Read in align output, store in a starset, and save in a digital format
        for fast reading in the future.
        """
        print "Fetching lists, dates, and integration times."
        roots, quads, dates, tints = Starlist.read_align_list(alignRoot)

        print "Reading in align output."
        s = starset.StarSet(alignRoot)

        x = s.getArrayFromAllEpochs('x')
        y = s.getArrayFromAllEpochs('y')
        m = s.getArrayFromAllEpochs('mag')

        print "Processing align output."
        # Save the first epoch as a reference.
        xref = x[0,:]
        yref = y[0,:]
        mref = m[0,:]

        # Drop the first epoch, a reference.
        x = x[1:,:]
        y = y[1:,:]
        m = m[1:,:]

        name = s.getArray('name')
        ndet = np.array(s.getArray('velCnt'), dtype=np.int16)

        # Set up mask to get rid of invalid values
        idx = x <= -1e5

        # For performance reasons, convert to dx and dy
        # and store in smaller array format.
        dx = np.array(x - xref, dtype=np.float32)
        dy = np.array(y - yref, dtype=np.float32)
        m = np.array(m, dtype=np.float16)

        # Create masked arrays
        dxm = np.ma.masked_where(idx, dx)
        dym = np.ma.masked_where(idx, dy)
        mm = np.ma.masked_where(idx, m)

        _out = open(alignRoot + '_xym.pickle', 'w')
        pickle.dump(name, _out)
        pickle.dump(ndet, _out)
        pickle.dump(xref, _out)
        pickle.dump(yref, _out)
        pickle.dump(mref, _out)
        pickle.dump(dxm, _out)
        pickle.dump(dym, _out)
        pickle.dump(mm, _out)
        pickle.dump(roots, _out)
        pickle.dump(quads, _out)
        pickle.dump(dates, _out)
        pickle.dump(tints, _out)
        _out.close()
Beispiel #7
0
def plotFitRms(root, polyroot, gcfitdir):
    s = starset.StarSet(root)
    s.loadPolyfit(polyroot, arcsec=1, accel=0)

    years = s.stars[0].years
    fitPx = s.getArray('fitXv.p')
    fitVx = s.getArray('fitXv.v')
    fitPy = s.getArray('fitYv.p')
    fitVy = s.getArray('fitYv.v')
    t0x = s.getArray('fitXv.t0')
    t0y = s.getArray('fitYv.t0')

    rmsX = na.zeros(len(s.stars), type=na.Float)
    rmsY = na.zeros(len(s.stars), type=na.Float)
    rms = na.zeros(len(s.stars), type=na.Float)
    cnt = na.zeros(len(s.stars), type=na.Int)

    for ee in range(len(years)):
        dtX = years[ee] - t0x
        dtY = years[ee] - t0y

        xfit = fitPx + (dtX * fitVx)
        yfit = fitPy + (dtY * fitVy)

        x = s.getArrayFromEpoch(ee, 'x')
        y = s.getArrayFromEpoch(ee, 'y')
        xpix = s.getArrayFromEpoch(ee, 'xpix')
        ypix = s.getArrayFromEpoch(ee, 'ypix')

        diffx = xfit - x
        diffy = yfit - y
        diff = na.sqrt(diffx**2 + diffy**2)

        idx = (na.where(xpix > -999))[0]

        rmsX[idx] += diffx**2
        rmsY[idx] += diffy**2
        rms[idx] += diff**2
        cnt[idx] += 1

    rmsX = na.sqrt(rmsX / cnt) * 1000.0
    rmsY = na.sqrt(rmsY / cnt) * 1000.0
    rms = na.sqrt(rms / cnt) * 1000.0

    mag = s.getArray('mag')
    x = s.getArray('x')
    y = s.getArray('y')
    r = na.sqrt(x**2 + y**2)

    idx = (na.where(mag < 15))[0]

    p.clf()
    p.semilogy(r[idx], rms[idx], 'k.')
Beispiel #8
0
def align_res(target,
              date,
              prefix='a',
              Kcut=18,
              weight=4,
              transform=4,
              export=False,
              root='/u/nijaid/work/',
              main_out='/u/nijaid/microlens/paper_plots/'):
    work_dir = root + target.upper() + '/' + prefix + '_' + date + '/'

    align_dir = work_dir + prefix + '_' + target + '_' + date + '_a' + str(
        transform) + '_m' + str(Kcut) + '_w' + str(weight) + '_MC100/'
    s = starset.StarSet(align_dir + 'align/align_t')
    s.loadPolyfit(align_dir + 'polyfit_d/fit', accel=0, arcsec=0)

    names = s.getArray('name')
    i = names.index(target)
    star = s.stars[i]

    pointsTab = Table.read(align_dir + 'points_d/' + target + '.points',
                           format='ascii')
    time = np.array(pointsTab[pointsTab.colnames[0]])
    x = pointsTab[pointsTab.colnames[1]]
    y = pointsTab[pointsTab.colnames[2]]
    xerr = pointsTab[pointsTab.colnames[3]] * 9.95
    yerr = pointsTab[pointsTab.colnames[4]] * 9.95

    fitx = star.fitXv
    fity = star.fitYv
    dt = time - fitx.t0
    fitLineX = fitx.p + (fitx.v * dt)
    fitLineY = fity.p + (fity.v * dt)

    resX = (x - fitLineX) * 9.95
    resY = (y - fitLineY) * 9.95

    fmt = '{0:.3f}: dx = {1:6.3f}  dy = {2:6.3f}  xe = {3:6.3f}  ye = {3:6.3f}'
    for yy in range(len(time)):
        print(fmt.format(time[yy], resX[yy], resY[yy], xerr[yy], yerr[yy]))

    if export:
        out_dir = main_out + 'align_res_' + target + '_' + date + '_a' + str(
            transform) + '_m' + str(Kcut) + '_w' + str(weight)
        _out = open(out_dir + '.txt', 'w')

        pfmt = fmt + '\n'
        for yy in range(len(time)):
            _out.write(
                pfmt.format(time[yy], resX[yy], resY[yy], xerr[yy], yerr[yy]))

        _out.close()
Beispiel #9
0
def plotVelocityMap(root='./',
                    align='align/align_d_rms_1000_abs_t',
                    poly='polyfit_d/fit'):

    s = starset.StarSet(root + align)
    s.loadPolyfit(root + poly)

    x = s.getArray('fitXv.p')
    y = s.getArray('fitYv.p')
    vx = s.getArray('fitXv.v')
    vy = s.getArray('fitYv.v')

    py.clf()
    arrScale = 1.0
    py.quiver([x], [y], [vx], [vy], scale=0.35, headwidth=3, color='black')
Beispiel #10
0
def velocityAverage(alignRoot, polyRoot, magCut=15):
    """
    Calculate the mean (and error on mean) of the velocities from
    a align/polyfit.

    Input Parameters:
    -- the root name of the align output (e.g. 'align/align_d_rms_t'
    -- the root name of the polyfit output( e.g. 'polyfit_d/fit')
    """
    # This should be an absolute aligned data set.
    cc = objects.Constants()
    s = starset.StarSet(alignRoot)
    s.loadPolyfit(polyRoot, accel=0)

    vx = s.getArray('fitXv.v') * 10**3
    vy = s.getArray('fitYv.v') * 10**3
    vxerr = s.getArray('fitXv.verr') * 10**3
    vyerr = s.getArray('fitYv.verr') * 10**3

    mag = s.getArray('mag')
    idx = np.where(mag <= magCut)[0]

    py.clf()
    py.hist(vx[idx])
    py.hist(vy[idx])

    print 'Number of Stars: %d' % len(idx)
    print 'X Mean Velocity: %5.2f' % (vx[idx].mean())
    print 'X Error on Mean: %5.2f' % (vx[idx].std() / math.sqrt(len(vx)))
    print 'Y Mean Velocity: %5.2f' % (vy[idx].mean())
    print 'Y Error on Mean: %5.2f' % (vy[idx].std() / math.sqrt(len(vx)))

    # Plot distribution of velocity errors
    py.clf()
    binsIn = np.arange(0, max([max(vxerr), max(vyerr)]), 0.1)
    (bins, data) = histNofill.hist(binsIn, vxerr)
    py.plot(bins, data, 'r', linewidth=2)
    (bins, data) = histNofill.hist(binsIn, vyerr)
    py.plot(bins, data, 'b', linewidth=2)
    py.axis([0, 10, 0, 600])
    py.xlabel('Velocity Errors (mas/yr)')
    py.ylabel('N')
    py.savefig('plots/histVelErr.png')
def confusionThreshold(starName1,
                       starName2,
                       root='./',
                       align='align/align_d_rms1000_t',
                       poly='polyfit_d/fit'):
    s = starset.StarSet(root + align)
    s.loadPolyfit(root + poly, arcsec=1, accel=0)

    names = s.getArray('name')
    id1 = names.index(starName1)
    id2 = names.index(starName2)

    star1 = s.stars[id1]
    star2 = s.stars[id2]

    years = np.array(star1.years)
    xfit1 = star1.fitXv.p + (star1.fitXv.v * (years - star1.fitXv.t0))
    yfit1 = star1.fitYv.p + (star1.fitYv.v * (years - star1.fitYv.t0))
    xfit2 = star2.fitXv.p + (star2.fitXv.v * (years - star2.fitXv.t0))
    yfit2 = star2.fitYv.p + (star2.fitYv.v * (years - star2.fitYv.t0))

    xdiff = xfit1 - xfit2
    ydiff = yfit1 - yfit2
    diff = hypot(xdiff, ydiff)

    for ee in range(len(years)):
        detected1 = (star1.e[ee].xpix > -999)
        detected2 = (star2.e[ee].xpix > -999)

        if (diff[ee] < 0.075):
            print '%8.3f   Close Approach: sep = %5.3f' % \
                  (years[ee], diff[ee])

            if ((detected1 == False) and (detected2 == False)):
                print '\tNeither source found... do nothing'
            if ((detected1 == False) and (detected2 == True)):
                print '\t%13s: Not found in this epoch' % (starName1)
                print '\t%13s: Remove point for this epoch' % (starName2)
            if ((detected2 == False) and (detected1 == True)):
                print '\t%13s: Not found in this epoch' % (starName2)
                print '\t%13s: Remove point for this epoch' % (starName1)
            if ((detected1 == True) and (detected2 == True)):
                print '\t   Found both sources... do nothing'
Beispiel #12
0
def updateLabelInfoWithDeepMosaic(oldLabelFile,
                                  dpMscAlignDir,
                                  outputFile,
                                  alignRoot='align/align_d_rms_100_abs_t',
                                  polyRoot='polyfit_100/fit'):
    """
    Modify an existing label.dat file with updated positions,
    velocities, and magnitudes from a dp_msc alignment.

    Input Parameters:
    oldLabelFile - The name of the input old label.dat file
    dpMscAlignDir - the root directory name of a dp_msc alignment
                    and polyfit (e.g. /u/jlu/work/gc/do_msc/2011_05_29/)
    outputFile - Save the modified label.dat content to a new file.
    """
    old = Labels(oldLabelFile)

    s = starset.StarSet(dpMscAlign + alignRoot)
    s.loadPolyfit(dpMscAlign + polyRoot, accel=0)
Beispiel #13
0
def plot_vpd_align(alignRoot, epoch1, epoch2, outRoot='plot_align'):
    """
    Read in an aligned data set. Plot a vector-point-diagram for the 
    positional differences between two different epochs within the data set.
    """
    s = starset.StarSet(alignRoot)

    x1 = s.getArrayFromEpoch(epoch1, 'xorig')
    y1 = s.getArrayFromEpoch(epoch1, 'yorig')
    x2 = s.getArrayFromEpoch(epoch2, 'xorig')
    y2 = s.getArrayFromEpoch(epoch2, 'yorig')

    x1e = s.getArrayFromEpoch(epoch1, 'xpixerr_p')
    y1e = s.getArrayFromEpoch(epoch1, 'ypixerr_p')
    x2e = s.getArrayFromEpoch(epoch2, 'xpixerr_p')
    y2e = s.getArrayFromEpoch(epoch2, 'ypixerr_p')

    dx = x2 - x1
    dy = y2 - y1
    dxe = np.hypot(x1e, x2e)
    dye = np.hypot(y1e, y2e)
    dr = np.hypot(dx, dy)

    idx = np.where((dxe < 0.02) & (dye < 0.02) & (dr < 3.0))[0]
    print len(x1), len(idx)

    drmax = 1.5

    py.figure(1)
    py.clf()
    py.plot(dx[idx], dy[idx], 'k.', ms=2)
    py.xlabel('Delta X (pixels)')
    py.ylabel('Delta Y (pixels)')
    py.axis([-drmax, drmax, -drmax, drmax])
    py.savefig(outRoot + '_vpd.png')

    py.figure(2)
    py.clf()
    q = py.quiver(x1[idx], y1[idx], dx[idx], dy[idx], scale=10)
    py.quiverkey(q, 0.5, 0.95, 0.05, '0.05 pix', color='red')
    py.savefig(outRoot + '_dr_vec.png')
Beispiel #14
0
def CompareTarget(TargetName,
                  root='./',
                  align='align/align_d_rms_1000_abs_t',
                  poly='polyfit_d/fit',
                  useAccFits=False):

    s = starset.StarSet(rootDir + align)
    s.loadPolyfit(rootDir + poly, accel=0, arcsec=0)
    names = s.getArray('name')
    indTarg = names.index(TargetName)
    star = s.stars[indTarg]

    pointsFile = root + points + TargetName + '.points'
    if os.path.exists(pointsFile + '.orig'):
        pointsTab = Table.read(pointsFile + '.orig', format='ascii')
    else:
        pointsTab = Table.read(pointsFile, format='ascii')

    # Observed Data
    time = pointsTab[pointsTab.colnames[0]]
    x = pointsTab[pointsTab.colnames[1]]
    y = pointsTab[pointsTab.colnames[2]]
    xerr = pointsTab[pointsTab.colnames[3]]
    yerr = pointsTab[pointsTab.colnames[4]]

    fitx = star.fitXv
    fity = star.fitYv
    dt = time - fitx.t0
    fitLineX = fitx.p + (fitx.v * dt)
    fitSigX = np.sqrt(fitx.perr**2 + (dt * fitx.verr)**2)

    fitLineY = fity.p + (fity.v * dt)
    fitSigY = np.sqrt(fity.perr**2 + (dt * fity.verr)**2)

    resTargX = x - fitLineX
    resTargY = y - fitliney

    diffEpX, diffEpY = sigmaVsEpoch(root=root,
                                    align=align,
                                    poly=poly,
                                    useAccFits=useAccFits)
def errVsMag(root, epoch):
    # Get the star set info
    s = starset.StarSet(root)

    xerr = s.getArrayFromEpoch(epoch, 'xerr_a')
    yerr = s.getArrayFromEpoch(epoch, 'yerr_a')
    mag = s.getArray('mag')

    idx = (np.where(xerr > 0))[0]
    mag = mag[idx]
    xerr = xerr[idx] * 1000.0
    yerr = yerr[idx] * 1000.0

    p.clf()
    p.semilogy(mag, xerr, 'bx')
    p.semilogy(mag, yerr, 'r+')
    p.axis([8, 17, 0.05, 5])

    p.xlabel('Magnitude')
    p.ylabel('Alignment Error (mas)')

    p.title('Epoch #%d:  %8.3f' % (epoch, s.stars[0].years[epoch]))
    p.savefig('plots/alignErrVsMag.png')
Beispiel #16
0
def plotVsMag(root='./',
              align='align/align_d_rms_t',
              poly='polyfit_d_points/fit',
              youngOnly=False,
              showLabels=False):

    # Load up our starlist
    s = starset.StarSet(root + align)
    s.loadPolyfit(root + poly, accel=0, arcsec=1)

    if (youngOnly):
        s.onlyYoungDisk()

    chiXred = s.getArray('fitXv.chi2red')
    chiYred = s.getArray('fitYv.chi2red')
    mag = s.getArray('mag')
    names = s.getArray('name')

    py.clf()
    py.subplot(2, 1, 1)
    py.plot(mag, chiXred, 'k^')
    py.xlabel('Magniutde')
    py.ylabel('X Reduced Chi-Sq')
    if (showLabels):
        for ii in range(len(names)):
            py.text(mag[ii], chiXred[ii], names[ii])
    py.ylim(0, 100)

    py.subplot(2, 1, 2)
    py.plot(mag, chiYred, 'k^')
    py.xlabel('Magniutde')
    py.ylabel('Y Reduced Chi-Sq')
    if (showLabels):
        for ii in range(len(names)):
            py.text(mag[ii], chiYred[ii], names[ii])

    py.ylim(0, 100)
def align_plot(root_dir='./', align_root='align'):
    s = starset.StarSet(root_dir + align_root)
    s.loadStarsUsed()

    x = s.getArrayFromAllEpochs('xpix')
    y = s.getArrayFromAllEpochs('ypix')
    xe_p = s.getArrayFromAllEpochs('xpixerr_p')
    ye_p = s.getArrayFromAllEpochs('ypixerr_p')
    xe_a = s.getArrayFromAllEpochs('xpixerr_a')
    ye_a = s.getArrayFromAllEpochs('ypixerr_a')
    isUsed = s.getArrayFromAllEpochs('isUsed')

    x0 = s.getArray('fitpXv.p')
    y0 = s.getArray('fitpYv.p')
    vx = s.getArray('fitpXv.v')
    vy = s.getArray('fitpYv.v')
    t0x = s.getArray('fitpXv.t0')
    t0y = s.getArray('fitpYv.t0')

    m = s.getArray('mag')
    cnt = s.getArray('velCnt')

    N_epochs = x.shape[0]
    N_stars = x.shape[1]

    # Setup arrays
    xresid_rms_all = np.zeros(N_epochs, dtype=float)
    yresid_rms_all = np.zeros(N_epochs, dtype=float)

    xresid_rms_used = xresid_rms_all
    yresid_rms_used = xresid_rms_all

    xresid_err_a_all = xresid_rms_all
    yresid_err_a_all = xresid_rms_all

    xresid_err_a_used = xresid_rms_all
    yresid_err_a_used = xresid_rms_all

    xresid_err_p_all = xresid_rms_all
    yresid_err_p_all = xresid_rms_all

    xresid_err_p_used = xresid_rms_all
    yresid_err_p_used = xresid_rms_all

    chi2x_all = xresid_rms_all
    chi2y_all = xresid_rms_all

    chi2x_used = xresid_rms_all
    chi2y_used = xresid_rms_all

    N_stars_all = xresid_rms_all
    N_stars_used = xresid_rms_all

    year = xresid_rms_all

    idx = np.where(cnt > 2)[0]
    N_stars_3ep = len(idx)

    for ee in range(N_epochs):
        idx = np.where((cnt > 2) & (x[ee, :] > -1000) & (xe_p[ee, :] > 0))[0]
        used = np.where(isUsed[ee, idx] == True)

        # Everything below should be arrays sub-indexed by "idx"
        dt_x = s.years[ee] - t0x[idx]
        dt_y = s.years[ee] - t0y[idx]

        x_fit = x0[idx] + (vx[idx] * dt_x)
        y_fit = y0[idx] + (vy[idx] * dt_y)

        xresid = x[ee, idx] - x_fit
        yresid = y[ee, idx] - y_fit

        N_stars_all[ee] = len(xresid)
        N_stars_used[ee] = len(xresid[used])

        # Note this chi^2 only includes positional errors.
        chi2x_terms = xresid**2 / xe_p[ee, idx]**2
        chi2y_terms = yresid**2 / ye_p[ee, idx]**2

        xresid_rms_all[ee] = np.sqrt(np.mean(xresid**2))
        yresid_rms_all[ee] = np.sqrt(np.mean(yresid**2))

        xresid_rms_used[ee] = np.sqrt(np.mean(xresid[used]**2))
        yresid_rms_used[ee] = np.sqrt(np.mean(yresid[used]**2))

        xresid_err_p_all[ee] = xe_p[ee, idx].mean() / N_stars_all[ee]**0.5
        yresid_err_p_all[ee] = ye_p[ee, idx].mean() / N_stars_all[ee]**0.5

        xresid_err_p_used[ee] = xe_p[ee,
                                     idx][used].mean() / N_stars_used[ee]**0.5
        yresid_err_p_used[ee] = ye_p[ee,
                                     idx][used].mean() / N_stars_used[ee]**0.5

        xresid_err_a_all[ee] = xe_a[ee, idx].mean() / N_stars_all[ee]**0.5
        yresid_err_a_all[ee] = ye_a[ee, idx].mean() / N_stars_all[ee]**0.5

        xresid_err_a_used[ee] = xe_a[ee,
                                     idx][used].mean() / N_stars_used[ee]**0.5
        yresid_err_a_used[ee] = ye_a[ee,
                                     idx][used].mean() / N_stars_used[ee]**0.5

        chi2x_all[ee] = chi2x_terms.sum()
        chi2y_all[ee] = chi2y_terms.sum()

        chi2x_used[ee] = chi2x_terms[used].sum()
        chi2y_used[ee] = chi2y_terms[used].sum()

        year[ee] = s.years[ee]

    data = {
        'xres_rms_all': xresid_rms_all,
        'yres_rms_all': yresid_rms_all,
        'xres_rms_used': xresid_rms_used,
        'yres_rms_used': yresid_rms_used,
        'xres_err_p_all': xresid_err_p_all,
        'yres_err_p_all': yresid_err_p_all,
        'xres_err_p_used': xresid_err_p_used,
        'yres_err_p_used': yresid_err_p_used,
        'xres_err_a_all': xresid_err_a_all,
        'yres_err_a_all': yresid_err_a_all,
        'xres_err_a_used': xresid_err_a_used,
        'yres_err_a_used': yresid_err_a_used,
        'chi2x_all': chi2x_all,
        'chi2y_all': chi2y_all,
        'chi2x_used': chi2x_used,
        'chi2y_used': chi2y_used,
        'N_stars_all': N_stars_all,
        'N_stars_used': N_stars_used,
        'year': year,
        'N_stars_3ep': N_stars_3ep
    }

    return data
Beispiel #18
0
def makeLabelDat(oldLabelFile,
                 root='./',
                 align='align/align_t',
                 poly='polyfit_d/fit',
                 addNewStars=True,
                 keepOldStars=True,
                 updateStarPosVel=True,
                 newUse=0,
                 rad_cut=None,
                 stars=None,
                 newLabelFile='label_new.dat'):
    """
    Make a new label.dat file using output from align and polyfit.

    Optional Inputs:
    root: The root of align analysis (e.g. './' or '07_05_18.')
    align: The root filename of the align output.
    poly: The root filename of the polyfit output.
    stars: A starset.StarSet() object with polyfit already loaded. 
           This overrides align/poly/root values and is useful for
           custom cuts that trim_align can't handle such as magnitude
           dependent velocity error cuts. BEWARE: stars may be modified.

    Outputs:
    source_list/label_new.dat

    Dependencies:
    Polyfit and align must contain the same numbers/names of stars. Also, 
    making the label.dat file depends on having the absolute astrometry
    done correctly. See gcwork.starset to learn about how the absolute
    astrometry is loaded (it depends on a specific reference epoch in align).

    You MUST run this on something that has already been run through 
    java align_absolute.
    """
    from gcwork import starset

    if stars == None:
        s = starset.StarSet(root + align)

        if (poly != None):
            s.loadPolyfit(root + poly)
            s.loadPolyfit(root + poly)
    else:
        s = stars

    # Trim out the new stars if we aren't going to add them
    if not addNewStars:
        idx = []
        for ss in range(len(s.stars)):
            if 'star' not in s.stars[ss].name:
                idx.append(ss)
        s.stars = [s.stars[ss] for ss in idx]

    # Get the 2D radius of all stars and sort
    radius = s.getArray('r2d')
    ridx = radius.argsort()
    s.stars = [s.stars[ss] for ss in ridx]

    # Get info for all the stars.
    names = np.array(s.getArray('name'))

    if poly != None:
        t0 = s.getArray('fitXv.t0')
        x = s.getArray('fitXv.p') * -1.0
        y = s.getArray('fitYv.p')
        xerr = s.getArray('fitXv.perr')
        yerr = s.getArray('fitYv.perr')
        vx = s.getArray('fitXv.v') * 995.0 * -1.0
        vy = s.getArray('fitYv.v') * 995.0
        vxerr = s.getArray('fitXv.verr') * 995.0
        vyerr = s.getArray('fitYv.verr') * 995.0
    else:
        t0 = s.getArray('fitXalign.t0')
        x = s.getArray('fitXalign.p') * -1.0
        y = s.getArray('fitYalign.p')
        xerr = s.getArray('fitXalign.perr')
        yerr = s.getArray('fitYalign.perr')
        vx = s.getArray('fitXalign.v') * 995.0 * -1.0
        vy = s.getArray('fitYalign.v') * 995.0
        vxerr = s.getArray('fitXalign.verr') * 995.0
        vyerr = s.getArray('fitYalign.verr') * 995.0

    x -= x[0]
    y -= y[0]
    r2d = np.sqrt(x**2 + y**2)
    mag = s.getArray('mag')

    # Fix Sgr A*
    idx = np.where(names == 'SgrA')[0]
    if (len(idx) > 0):
        x[idx] = 0
        y[idx] = 0
        vx[idx] = 0
        vy[idx] = 0
        vxerr[idx] = 0
        vyerr[idx] = 0
        r2d[idx] = 0

    # Clean up xerr and yerr so that they are at least 1 mas
    idx = np.where(xerr < 0.00001)[0]
    xerr[idx] = 0.00001
    idx = np.where(yerr < 0.00001)[0]
    yerr[idx] = 0.00001

    ##########
    # Load up the old star list and find the starting
    # point for new names.
    ##########
    oldLabels = Labels(labelFile=oldLabelFile)
    alnLabels = Labels(labelFile=oldLabelFile)
    newLabels = Labels(labelFile=oldLabelFile)

    if addNewStars:
        newNumber = calcNewNumbers(oldLabels.name, names)

    # Sort the old label list by radius just in case it
    # isn't already. We will update the radii first since
    # these sometimes get out of sorts.
    oldLabels.r = np.hypot(oldLabels.x, oldLabels.y)
    sidx = oldLabels.r.argsort()
    oldLabels.take(sidx)

    # Clean out the new label lists.
    newLabels.ourName = []
    newLabels.name = []
    newLabels.mag = []
    newLabels.x = []
    newLabels.y = []
    newLabels.xerr = []
    newLabels.yerr = []
    newLabels.vx = []
    newLabels.vy = []
    newLabels.vxerr = []
    newLabels.vyerr = []
    newLabels.t0 = []
    newLabels.useToAlign = []
    newLabels.r = []

    # Load up the align info into the alnLabels object
    alnLabels.ourName = names
    alnLabels.name = names
    alnLabels.mag = mag
    alnLabels.x = x
    alnLabels.y = y
    alnLabels.xerr = xerr
    alnLabels.yerr = yerr
    alnLabels.vx = vx
    alnLabels.vy = vy
    alnLabels.vxerr = vxerr
    alnLabels.vyerr = vyerr
    alnLabels.t0 = t0
    alnLabels.r = r2d

    def addStarFromAlign(alnLabels, ii, use):
        newLabels.ourName.append(alnLabels.ourName[ii])
        newLabels.name.append(alnLabels.name[ii])
        newLabels.mag.append(alnLabels.mag[ii])
        newLabels.x.append(alnLabels.x[ii])
        newLabels.y.append(alnLabels.y[ii])
        newLabels.xerr.append(alnLabels.xerr[ii])
        newLabels.yerr.append(alnLabels.yerr[ii])
        newLabels.vx.append(alnLabels.vx[ii])
        newLabels.vy.append(alnLabels.vy[ii])
        newLabels.vxerr.append(alnLabels.vxerr[ii])
        newLabels.vyerr.append(alnLabels.vyerr[ii])
        newLabels.t0.append(alnLabels.t0[ii])
        newLabels.useToAlign.append(use)
        newLabels.r.append(alnLabels.r[ii])

    def addStarFromOldLabels(oldLabels, ii):
        newLabels.ourName.append(oldLabels.name[ii])
        newLabels.ourName.append(oldLabels.ourName[ii])
        newLabels.name.append(oldLabels.name[ii])
        newLabels.mag.append(oldLabels.mag[ii])
        newLabels.x.append(oldLabels.x[ii])
        newLabels.y.append(oldLabels.y[ii])
        newLabels.xerr.append(oldLabels.xerr[ii])
        newLabels.yerr.append(oldLabels.yerr[ii])
        newLabels.vx.append(oldLabels.vx[ii])
        newLabels.vy.append(oldLabels.vy[ii])
        newLabels.vxerr.append(oldLabels.vxerr[ii])
        newLabels.vyerr.append(oldLabels.vyerr[ii])
        newLabels.t0.append(oldLabels.t0[ii])
        newLabels.useToAlign.append(oldLabels.useToAlign[ii])
        newLabels.r.append(oldLabels.r[ii])

    def deleteFromAlign(alnLabels, idx):
        # Delete them from the align lists.
        alnLabels.ourName = np.delete(alnLabels.ourName, idx)
        alnLabels.name = np.delete(alnLabels.name, idx)
        alnLabels.mag = np.delete(alnLabels.mag, idx)
        alnLabels.x = np.delete(alnLabels.x, idx)
        alnLabels.y = np.delete(alnLabels.y, idx)
        alnLabels.xerr = np.delete(alnLabels.xerr, idx)
        alnLabels.yerr = np.delete(alnLabels.yerr, idx)
        alnLabels.vx = np.delete(alnLabels.vx, idx)
        alnLabels.vy = np.delete(alnLabels.vy, idx)
        alnLabels.vxerr = np.delete(alnLabels.vxerr, idx)
        alnLabels.vyerr = np.delete(alnLabels.vyerr, idx)
        alnLabels.t0 = np.delete(alnLabels.t0, idx)
        alnLabels.r = np.delete(alnLabels.r, idx)

    # Radial cut
    if rad_cut != None:
        cut = []
        for rr in range(len(alnLabels.name)):
            if alnLabels.r[rr] > rad_cut:
                cut.append(rr)

        deleteFromAlign(alnLabels, cut)

    nn = 0
    while nn < len(oldLabels.name):
        #
        # First see if there are any new stars that should come
        # before this star.
        #
        if addNewStars:

            def filterFunction(i):
                return (alnLabels.r[i] <
                        oldLabels.r[nn]) and ('star' in alnLabels.name[i])

            idx = filter(filterFunction, range(len(alnLabels.name)))

            for ii in idx:
                rAnnulus = int(math.floor(alnLabels.r[ii]))
                number = newNumber[rAnnulus]
                alnLabels.name[ii] = 'S%d-%d' % (rAnnulus, number)
                newNumber[rAnnulus] += 1

                # Insert these new stars.
                addStarFromAlign(alnLabels, ii, newUse)

            # Delete these stars from the align info.
            deleteFromAlign(alnLabels, idx)

        #
        # Now look for this star in the new align info
        #
        idx = np.where(alnLabels.name == oldLabels.name[nn])[0]

        if len(idx) > 0:
            # Found the star

            if updateStarPosVel:
                # Update with align info
                addStarFromAlign(alnLabels, idx[0], oldLabels.useToAlign[nn])
            else:
                # Don't update with align info
                addStarFromOldLabels(oldLabels, nn)

            deleteFromAlign(alnLabels, idx[0])

        elif keepOldStars:
            # Did not find the star. Only keep if user said so.
            addStarFromOldLabels(oldLabels, nn)

        nn += 1

    # Add the rest
    for gg in range(len(alnLabels.name)):
        addStarFromAlign(alnLabels, gg, newUse)

    # Quick verification that we don't have repeated names.
    uniqueNames = np.unique(newLabels.name)
    if len(uniqueNames) != len(newLabels.name):
        print('Problem, we have a repeat name!!')

    # Write to output
    newLabels.saveToFile(root + 'source_list/' + newLabelFile)
Beispiel #19
0
def accuracyFromResiduals(radiusCut=4):
    rootDir = '/u/jlu/work/gc/proper_motion/align/09_06_01/'
    alignRoot = 'align/align_d_rms_1000_abs_t'
    polyRoot = 'polyfit_d/fit'
    pointsRoot = 'points_d/'

    # Load starset
    s = starset.StarSet(rootDir + alignRoot)
    s.loadPolyfit(rootDir + polyRoot, accel=0, arcsec=0)

    # Keep only those stars in ALL epochs
    epochCnt = s.getArray('velCnt')
    idx = np.where(epochCnt == epochCnt.max())[0]
    newstars = []
    for i in idx:
        newstars.append(s.stars[i])
    s.stars = newstars

    mag = s.getArray('mag')
    x = s.getArray('x')
    y = s.getArray('y')
    r = np.hypot(x, y)

    # Trim on radius
    if (radiusCut != None):
        idx = np.where(r < radiusCut)[0]

        newstars = []
        for i in idx:
            newstars.append(s.stars[i])
        s.stars = newstars

        mag = mag[idx]
        x = x[idx]
        y = y[idx]
        r = r[idx]

    # Define some arrays we will keep.
    numStars = len(s.stars)

    medErrX = np.zeros(numStars, dtype=float)
    medErrY = np.zeros(numStars, dtype=float)
    medErr = np.zeros(numStars, dtype=float)
    medResX = np.zeros(numStars, dtype=float)
    medResY = np.zeros(numStars, dtype=float)
    medRes = np.zeros(numStars, dtype=float)

    for ss in range(numStars):
        star = s.stars[ss]
        starName = star.name

        pointsFile = rootDir + pointsRoot + starName + '.points'
        pointsTab = asciidata.open(pointsFile)

        # Observed Data
        t = pointsTab[0].tonumpy()
        x = pointsTab[1].tonumpy()
        y = pointsTab[2].tonumpy()
        xerr = pointsTab[3].tonumpy()
        yerr = pointsTab[4].tonumpy()

        # Best fit velocity model
        fitx = star.fitXv
        fity = star.fitYv

        dt = t - fitx.t0
        fitLineX = fitx.p + (fitx.v * dt)
        fitLineY = fity.p + (fity.v * dt)

        # Residuals
        diffx = x - fitLineX
        diffy = y - fitLineY
        diff = np.hypot(diffx, diffy)

        medErrX[ss] = np.median(xerr)
        medErrY[ss] = np.median(yerr)
        medErr[ss] = np.median((xerr + yerr) / 2.0)
        medResX[ss] = np.median(diffx)
        medResY[ss] = np.median(diffy)
        medRes[ss] = np.median(diff)

    # Convert into milliarcsec
    medErrX *= 10**3
    medErrY *= 10**3
    medErr *= 10**3
    medResX *= 10**3
    medResY *= 10**3
    medRes *= 10**3

    # Bins stars vs. magnitude
    magStep = 1.0
    magBins = np.arange(10.0, 20.0, magStep)

    medErrMag = np.zeros(len(magBins), dtype=float)
    medResMag = np.zeros(len(magBins), dtype=float)

    for mm in range(len(magBins)):
        mMin = magBins[mm] - (magStep / 2.0)
        mMax = magBins[mm] + (magStep / 2.0)
        idx = np.where((mag >= mMin) & (mag < mMax))[0]

        if (len(idx) > 0):
            medErrMag[mm] = np.median(medErr[idx])
            medResMag[mm] = np.median(medRes[idx])

    # Plot
    outdir = '/u/jlu/work/gc/astrometry/lgsao/plots/'

    py.clf()
    py.semilogy(magBins, medErrMag)
    py.semilogy(magBins, medResMag)
    py.legend(('Precision', 'Accuracy'))
    py.title('Keck AO Relative Astrometry')
    py.xlabel('K Magnitude for r < %4.1f"' % radiusCut)
    py.ylabel('Pos. Uncertainty (mas)')

    py.savefig(outdir + 'accuracy_from_residuals_log.png')

    py.clf()
    py.plot(magBins, medErrMag)
    py.plot(magBins, medResMag)
    py.legend(('Precision', 'Accuracy'))
    py.title('Keck AO Relative Astrometry')
    py.xlabel('K Magnitude for r < %4.1f"' % radiusCut)
    py.ylabel('Pos. Uncertainty (mas)')
    py.ylim(0, 2.0)

    py.savefig(outdir + 'accuracy_from_residuals_lin.png')

    foo = np.where((mag >= 11) & (mag <= 14))[0]
    print 'Median Precisions for K=11-14: ', np.median(medErr[foo])
    print 'Median Accuracy for K=11-14: ', np.median(medRes[foo])

    _logfile = open(outdir + 'accuracy_from_residuals.log', 'w')
    _logfile.write('Median Precisions for K=11-14: %5.2f\n' %
                   np.median(medErr[foo]))
    _logfile.write('Median Accuracy for K=11-14:   %5.2f\n' %
                   np.median(medRes[foo]))
    _logfile.close()
Beispiel #20
0
def labelRestrict(inputLabel,
                  outputLabel,
                  alignInput,
                  numSpeck=None,
                  numAO=None):
    """
    Modify an existing label.dat file to be used with the align
    -restrict flag. This is the program that chooses which stars
    are to be used for speckle alignment and which are to be
    used for AO alignment. The stars are chosen based on the
    number of detections in either speckle or AO.
    We will use the subset of stars in ALL speckle epochs as speckle
    alignment sources; and those stars that are in ALL AO epochs
    are used as AO alignment sources. The input align files should
    not have been trimmed for the most part.

    Be sure that there is an <alignInput>.list file containing
    the epochs and their data types.

    Paramters:
    inputLabel -- the input label.dat file. This will not be modified.
    outputLabel -- the output label.dat file. Only the use? column is changed.
    alignInput -- the root name of the align files to be used when
                  determining how many speckle and AO maps a stars is found in.
    numSpeck -- if None then only stars in ALL speckle epochs are used
                as alignment sources.
    numAO -- if None then only stars in ALL AO epochs are used as
             alignment sources.
    """
    from gcwork import starset

    labels = Labels(labelFile=inputLabel)
    s = starset.StarSet(alignInput)

    # Figure out the data/camera type for each epoch (speckle or AO)
    _list = open(alignInput + '.list', 'r')
    aoEpochs = []
    spEpochs = []

    i = 0
    for line in _list:
        info = line.split()
        aoType = int(info[1])

        if ((aoType == 2) or (aoType == 3)):
            spEpochs.append(i)
        if ((aoType == 8) or (aoType == 9)):
            aoEpochs.append(i)

        i += 1

    if (numSpeck == None):
        numSpeck = len(spEpochs)
    if (numAO == None):
        numAO = len(aoEpochs)

    # For each star, count up the number of speckle and AO epochs it is
    # detected in.
    names = s.getArray('name')
    velCnt = s.getArray('velCnt')

    numStars = len(names)
    numEpochs = len(s.stars[0].years)

    print('Initial:  Nstars = %4d  Nepochs = %2d' % (numStars, numEpochs))
    print('Number of Epochs of Type:')
    print('   Speckle = %d' % len(spEpochs))
    print('   AO      = %d' % len(aoEpochs))

    aoCnt = np.zeros(numStars)
    spCnt = np.zeros(numStars)

    for e in range(numEpochs):
        pos = s.getArrayFromEpoch(e, 'x')

        idx = (np.where(pos > -1000))[0]

        if (e in aoEpochs):
            aoCnt[idx] += 1
        if (e in spEpochs):
            spCnt[idx] += 1

    # Now lets write the output
    _out = open(outputLabel, 'w')
    _out.write('%-10s  %5s   ' % ('#Name', 'K'))
    _out.write('%7s %7s %7s %7s   ' % ('x', 'y', 'xerr', 'yerr'))
    _out.write('%8s %8s %8s %8s   ' % ('vx', 'vy', 'vxerr', 'vyerr'))
    _out.write('%8s %4s %7s\n' % ('t0', 'use?', 'r2d'))

    _out.write('%-10s  %5s   ' % ('#()', '(mag)'))
    _out.write('%7s %7s %7s %7s   ' % \
               ('(asec)', '(asec)', '(asec)', '(asec)'))
    _out.write('%8s %8s %8s %8s   ' % \
               ('(mas/yr)', '(mas/yr)', '(mas/yr)', '(mas/yr)'))
    _out.write('%8s %4s %7s\n' % ('(year)', '()', '(asec)'))

    spNumStars = 0
    aoNumStars = 0
    use = '1'
    for i in range(len(labels.name)):
        # Find this star in our align output
        try:
            foo = names.index(labels.name[i])

            if (labels.useToAlign[i] == 0):
                # Preserve any pre-existing use?=0 stars
                use = '0'

                if (spCnt[foo] >= numSpeck):
                    print('%-13s is in all speckle epochs, but use=0' % \
                          names[foo])
            else:
                if (spCnt[foo] >= numSpeck):
                    use = '2'
                    spNumStars += 1

                if (aoCnt[foo] >= numAO):
                    aoNumStars += 1

                    if (use == '2'):
                        # Speckle and AO
                        use += ',8'
                    else:
                        # AO only
                        use = '8'

        except ValueError:
            # Don't change anything if we didn't find it.
            # Reformat to string for ease of use
            use = str(labels.useToAlign[i])

        _out.write('%-10s  %5.1f   ' % (labels.name[i], labels.mag[i]))
        _out.write('%7.3f %7.3f ' % (labels.x[i], labels.y[i]))
        _out.write('%7.3f %7.3f   ' % (labels.xerr[i], labels.yerr[i]))
        _out.write('%8.3f %8.3f ' % (labels.vx[i], labels.vy[i]))
        _out.write('%8.3f %8.3f   ' % (labels.vxerr[i], labels.vyerr[i]))
        _out.write('%8.3f %-4s %7.3f\n' %  \
                   (labels.t0[i], use, labels.r[i]))

    _out.close()

    print('Final:   Nstars Speckle = %4d  AO = %4d' % \
          (spNumStars, aoNumStars))
Beispiel #21
0
def makeNewRefList(alignRoot, refList, starPrefix='ep0'):
    print 'Making new reference list', refList
    s = starset.StarSet(alignRoot)

    # Get the zeropoint offset to convert to 
    magRef = s.getArrayFromEpoch(0, 'mag')
    magLis = s.getArrayFromEpoch(1, 'mag')

    idx = np.where((magRef != 0) & (magLis != 0))[0]
    # Only use the first 10 stars
    if len(idx) > 10:
        idx = idx[0:10]

    zp = (magRef[idx] - magLis[idx]).mean()
    print 'Zeropoint for %s is %.2f' % (starPrefix, zp)

    _out = open(refList, 'w')

    for star in s.stars:
        inRef = False
        inLis = False
        
        if star.e[0].x > -999: 
            inRef = True
        if star.e[1].x > -999: 
            inLis = True

        if inRef and inLis:

            name = star.e[0].name

            # Rename new stars from the mosaiced images.
            # Don't rename reference list sources, so we can reject 
            # them later on.
            if name.startswith('star') and starPrefix != None:
                name = star.e[1].name.replace('star', starPrefix)

            # get errors and combine them
            # centroid, distortion, and residual distortion
            xe0 = star.e[0].xpixerr_p 
            ye0 = star.e[0].ypixerr_p
            # centroid, distortion, and residual distortion
            xe1 = star.e[1].xpixerr_p 
            ye1 = star.e[1].ypixerr_p
            # align error
            xea = star.e[1].xpixerr_a 
            yea = star.e[1].ypixerr_a

            # add the alignment error in quadrature to the frame's other errors
            xe1_tot = np.hypot(xe1, xea)
            ye1_tot = np.hypot(ye1, yea)

            m = star.e[1].mag + zp

            # get original and aligned positions, then take weighted ave
            # weight by each field's errors (which contain centroid,
            # distortion, and residual distortion errors already)
            x0 = star.e[0].xpix
            y0 = star.e[0].ypix
            x1 = star.e[1].xpix
            y1 = star.e[1].ypix
            xwt0 = 1. / xe0**2
            ywt0 = 1. / ye0**2
            xwt1 = 1. / xe1_tot**2
            ywt1 = 1. / ye1_tot**2

            x = statsWeighted.mean_wgt(np.array([x0,x1]), np.array([xwt0,xwt1]))
            y = statsWeighted.mean_wgt(np.array([y0,y1]), np.array([ywt0,ywt1]))

            # For the next reference list's new positional error, we'll
            # take the average error of the ref and lis errors
            xerr = (xe0 + xe1_tot) / 2.0
            yerr = (ye0 + ye1_tot) / 2.0
        else:
            if inRef:
                name = star.e[0].name
                x = star.e[0].xpix
                y = star.e[0].ypix
                xe = star.e[0].xpixerr_p
                ye = star.e[0].ypixerr_p
                m = star.e[0].mag
                # just maintain the frame's (centroid+distortion+residual) 
                # errors
                xerr = xe 
                yerr = ye

            if inLis:
                name = star.e[1].name

                # Rename new stars from the narrow camera stuff.
                # Don't rename wide camera sources, so we can reject 
                # them later on.
                if name.startswith('star') and starPrefix != None:
                    name = name.replace('star', starPrefix)

                x = star.e[1].xpix
                y = star.e[1].ypix
                xe = star.e[1].xpixerr_p
                ye = star.e[1].ypixerr_p
                xea = star.e[1].xpixerr_a
                yea = star.e[1].ypixerr_a
                m = star.e[1].mag + zp
                # just maintain the frame's (centroid+distortion+residual) 
                # errors.
                xerr = xe 
                yerr = ye


        date = star.years[0]
        
        _out.write('%-13s %6.3f  %9.4f  %11.5f %11.5f  %8.5f %8.5f  1 1 1 1\n' %
                      (name, m, date, x, y, xerr, yerr))

    _out.close()
def plotLabelAndAlign(alignRoot,
                      polyRoot,
                      magCut=25,
                      labelFile='label.dat',
                      showStars=True):

    label = starTables.Labels(labelFile)
    label.take(np.where(label.mag < magCut)[0])

    t = 2005.580
    x_lab = label.x + label.vx * (t - label.t0) / 10**3
    y_lab = label.y + label.vy * (t - label.t0) / 10**3
    n_lab = label.ourName
    use = label.useToAlign

    # Now read in the align stuff
    s = starset.StarSet(alignRoot)
    s.loadPolyfit(polyRoot, accel=0)
    mag = s.getArray('mag')
    idx = np.where(mag < magCut)[0]
    s.stars = [s.stars[ii] for ii in idx]

    n_aln = np.array(s.getArray('name'))
    mag = s.getArray('mag')
    x0 = s.getArray('fitXv.p') * -1.0
    y0 = s.getArray('fitYv.p')
    x0err = s.getArray('fitXv.perr')
    y0err = s.getArray('fitYv.perr')
    vx = s.getArray('fitXv.v') * -1.0
    vy = s.getArray('fitYv.v')
    vxerr = s.getArray('fitXv.verr')
    vyerr = s.getArray('fitYv.verr')
    t0x = s.getArray('fitXv.t0')
    t0y = s.getArray('fitYv.t0')
    r = np.hypot(x0, y0)

    x_aln = x0 + vx * (t - t0x)
    y_aln = y0 + vy * (t - t0y)

    # Fix x0err, y0err to some minimum value
    idx = np.where(x0err < 0.0001)[0]
    x0err[idx] = 0.0001
    idx = np.where(y0err < 0.0001)[0]
    y0err[idx] = 0.0001

    # First lets update the 16 sources since they are used
    # to align label.dat to the reference epoch (crude I know)
    names16 = [
        'irs16C', 'irs16NW', 'irs16CC', 'irs16NE', 'irs16SW', 'irs16SW-E',
        'irs33N', 'irs33E'
    ]
    for nn in range(len(names16)):
        idx = np.where(n_aln == names16[nn])[0]

        for rr in idx:
            print '%-11s  %4.1f    %6.3f  %6.3f  %7.4f %7.4f  %8.3f %8.3f  %7.3f  %7.3f   %8.3f    1   %5.3f' % \
                  (n_aln[rr], mag[rr], x0[rr], y0[rr], x0err[rr],
                   y0err[rr], vx[rr]*10**3, vy[rr]*10**3,
                   vxerr[rr]*10**3, vyerr[rr]*10**3, t0x[rr], r[rr])

    # Image
    imageFile = '/u/ghezgroup/data/gc/'
    imageFile += '06maylgs1/combo/mag06maylgs1_dp_msc_kp.fits'
    im = pyfits.getdata(imageFile)
    imgsize = (im.shape)[0]

    # pixel position (0,0) is at upper left
    xpix = np.arange(0, im.shape[0], dtype=float)
    ypix = np.arange(0, im.shape[1], dtype=float)

    sgra = [1422.6, 1543.8]
    scale_jpg = 0.00994
    xim = (xpix - sgra[0]) * scale_jpg * -1.0
    yim = (ypix - sgra[1]) * scale_jpg

    # Lets also make some coordinates for compass rose and scale bar
    xrose = np.array([-15.5, -15.5])
    yrose = np.array([15.5, 15.5])
    xroseLen = np.array([20.0, 0.0])
    yroseLen = np.array([0.0, 20.0])

    py.clf()
    py.close(1)
    py.close(2)

    def drawImage(xlo, xhi, ylo, yhi):
        py.figure(2, figsize=(9, 9))
        py.grid(True)
        py.subplots_adjust(left=0.05, right=0.95, bottom=0.05, top=0.95)
        py.imshow(np.log10(im),
                  extent=[xim[0], xim[-1], yim[0], yim[-1]],
                  aspect='equal',
                  vmin=2.0,
                  vmax=4.0,
                  cmap=py.cm.gray)
        py.xlabel('X Offset from Sgr A* (arcsec)')
        py.ylabel('Y Offset from Sgr A* (arcsec)')
        py.title('UCLA/Keck Galactic Center Group',
                 fontsize=20,
                 fontweight='bold')
        thePlot = py.gca()

        # Plot label.dat points
        py.plot(x_lab, y_lab, 'rs')
        for ii in range(len(x_lab)):
            py.text(x_lab[ii], y_lab[ii], n_lab[ii], color='red', fontsize=10)

        # Plot align points
        py.plot(x_aln, y_aln, 'bo')
        for ii in range(len(x_aln)):
            py.text(x_aln[ii], y_aln[ii], n_aln[ii], color='blue', fontsize=10)

        py.axis([xlo, xhi, ylo, yhi])

    # We can do some matching here to help us out.
    drawImage(15, -15, -15, 15)

    if showStars:
        fmt = '%-11s   %4.1f   %9.5f %9.5f   %8.5f  %8.5f  %8.3f %8.3f  %7.3f  %7.3f   %8.3f    %1d   %5.3f\n'
        gcutil.rmall(['label_updated.dat'])
        out = open('label_updated.dat', 'w')

        out.write(
            '#Name           K         x       y           xerr      yerr       vx       vy    vxerr    vyerr         t0  use?    r2d\n'
        )
        out.write(
            '#()         (mag)      (asec)    (asec)     (asec)    (asec)  (mas/yr) (mas/yr) (mas/yr) (mas/yr)     (year)   ()  (asec)\n'
        )
        foo = raw_input('Continue?')
        for ss in range(len(x_lab)):
            update = 0

            idx = np.where(n_aln == n_lab[ss])[0]

            # The rest of the code allows us to find stars that were not matched
            # between the old label and new absolute alignment.
            # This will write out the new info from absolute alignment to a new
            # label_updated.dat file for just those stars that weren't matched properly,
            # but still need to run updateLabelInfoWithAbsRefs() to update the info
            # for stars that were matched.
            if len(idx) == 0:
                dr = np.hypot(x_aln - x_lab[ss], y_aln - y_lab[ss])

                rdx = np.where(dr < 0.2)[0]

                if len(rdx) > 0:
                    xlo = x_lab[ss] + 0.2
                    xhi = x_lab[ss] - 0.2
                    ylo = y_lab[ss] - 0.2
                    yhi = y_lab[ss] + 0.2
                    py.axis([xlo, xhi, ylo, yhi])

                    print 'Did not find a match for %s (K=%4.1f  x=%7.3f y = %7.3f):' % \
                          (n_lab[ss], label.mag[ss], x_lab[ss], y_lab[ss])

                    for rr in rdx:
                        print fmt % \
                              (n_aln[rr], mag[rr], x0[rr], y0[rr], x0err[rr],
                               y0err[rr], vx[rr]*10**3, vy[rr]*10**3,
                               vxerr[rr]*10**3, vyerr[rr]*10**3, t0x[rr], use[ss], r[rr])

                        # if the starname in align has the same ending as the name in
                        # label.dat, it's likely the same star (e.g. '1S9-87' and 'S9-87';
                        # Note that this is the naming used in mosaicked star list analysis)
                        if n_aln[rr].endswith(n_lab[ss]):
                            # do a check that these stars have similar magnitudes
                            if np.abs(label.mag[ss] - mag[rr]) <= 0.5:
                                update = 1
                                # replace the whole line in label_updated.dat
                                out.write(fmt % \
                                          (n_lab[ss], mag[rr], x0[rr], y0[rr], x0err[rr],
                                           y0err[rr], vx[rr]*10**3, vy[rr]*10**3,
                                           vxerr[rr]*10**3, vyerr[rr]*10**3, t0x[rr], use[ss], r[rr]))
                                continue
                            else:
                                foo = raw_input(
                                    'Similar names, but magnitudes are off. Check star %s manually and decide whether or not to replace it in label_updated.dat when this program completes. Hit enter to continue.'
                                    % n_aln[rr])

                        # Or the star just wasn't matched with any star in the old label.dat file
                        # and was given an arbitrary name
                        elif (('star' in n_aln[rr]) | ('ep' in n_aln[rr])):
                            print 'Manually check and update this star if needed:'
                            print 'Name in label: %s' % n_lab[ss]
                            print 'Name in new alignment: %s' % n_aln[rr]
                            if len(rdx) > 1:
                                print 'CAUTION: There are other nearby stars, including:'
                                for ii in range(len(rdx)):
                                    print n_aln[rdx[ii]]
                            update = raw_input(
                                'Update with %s velocity? (enter 1 for yes; 0 for no) '
                                % n_aln[rr])
                            update = int(update)
                            if update == 1:
                                out.write(fmt % \
                                          (n_lab[ss], mag[rr], x0[rr], y0[rr], x0err[rr],
                                           y0err[rr], vx[rr]*10**3, vy[rr]*10**3,
                                           vxerr[rr]*10**3, vyerr[rr]*10**3, t0x[rr], use[ss], r[rr]))
                            # check magnitude offset
                            #if np.abs(label.mag[ss] - mag[rr]) <= 0.5:
                            #    update = 1
                            #    # replace the whole line in label_updated.dat
                            #    out.write(fmt % \
                            #              (n_lab[ss], mag[rr], x0[rr], y0[rr], x0err[rr],
                            #               y0err[rr], vx[rr]*10**3, vy[rr]*10**3,
                            #               vxerr[rr]*10**3, vyerr[rr]*10**3, t0x[rr], 1, r[rr]))

            if update == 0:
                # just re-write what was in label.dat, and later run
                # updateLabelInfoWithAbsRefs() to update matched stars with the new
                # absolute alignment
                out.write(fmt % \
                          (label.ourName[ss], label.mag[ss], label.x[ss], label.y[ss],
                          label.xerr[ss], label.yerr[ss], label.vx[ss], label.vy[ss],
                          label.vxerr[ss], label.vyerr[ss], label.t0[ss], use[ss],
                          label.r[ss]))

        out.close()
Beispiel #23
0
def histogram(root='./',
              align='align/align_d_rms_t',
              poly='polyfit_d_points/fit',
              accel=False,
              youngOnly=False,
              trimMaxEpochs=True):

    s = starset.StarSet(root + align)
    s.loadPolyfit(root + poly, arcsec=1, accel=accel)

    if (youngOnly):
        s.onlyYoungDisk()

    if (accel):
        chi2Xred = s.getArray('fitXa.chi2red')
        chi2Yred = s.getArray('fitYa.chi2red')
        chi2X = s.getArray('fitXa.chi2')
        chi2Y = s.getArray('fitYa.chi2')
        dof = s.getArray('fitXa.dof')
    else:
        chi2Xred = s.getArray('fitXv.chi2red')
        chi2Yred = s.getArray('fitYv.chi2red')
        chi2X = s.getArray('fitXv.chi2')
        chi2Y = s.getArray('fitYv.chi2')
        dof = s.getArray('fitXv.dof')

    cnt = s.getArray('velCnt')

    if trimMaxEpochs:
        idx = np.where(cnt == cnt.max())[0]
        chi2Xred = chi2Xred[idx]
        chi2Yred = chi2Yred[idx]
        chi2X = chi2X[idx]
        chi2Y = chi2Y[idx]
        dof = dof[idx]
        cnt = cnt[idx]

    # ==========
    # First histograms on the chi2 (not reduced)
    # ==========

    # Plot the unreduced distribution
    binSize = np.median(chi2X) / 10.0
    binsIn = np.arange(0, dof.max() * 100, binSize)
    binScale = 100.0
    binsInModel = np.arange(0, dof.max() * 100, binSize / binScale)
    chi2model = np.zeros(len(binsInModel), dtype=float)

    # Make a model distribution using the appropriate degrees of
    # freedom for all the stars.
    maxEpochCnt = cnt.max()
    minEpochCnt = cnt.min()

    for ii in range(minEpochCnt, maxEpochCnt + 1):
        idx = np.where(cnt == ii)[0]

        if len(idx) > 0:
            chi2 = scipy.stats.chi2(dof[idx[0]])

            # Get PDF, and then convert to histogram with the
            # Same prob/bin as our data histogram
            tmp = chi2.pdf(binsInModel) * len(idx) * binSize

            # Add to our model
            chi2model += tmp

    # Plot up the results
    py.clf()

    # X
    py.subplot(2, 1, 1)
    (n, bins, p) = py.hist(chi2X, bins=binsIn, alpha=0.6)
    p1 = py.plot(binsInModel, chi2model)
    py.xlim(0, dof.max() * 5)
    py.ylabel('Number of Stars')
    py.xlabel('X Velocity Fit Chi^2')
    py.title('%d stars in %d-%d Epochs' %
             (len(chi2Xred), cnt.min(), cnt.max()))

    # Y
    py.subplot(2, 1, 2)
    (n, bins, p) = py.hist(chi2Y, bins=binsIn, alpha=0.6)
    p1 = py.plot(binsInModel, chi2model)
    py.xlim(0, dof.max() * 5)
    py.ylabel('Number of Stars')
    py.xlabel('Y Velocity Fit Chi^2')

    if trimMaxEpochs:
        outputFile = root + 'plots/poly_chi2_hist_max_dof.png'
    else:
        outputFile = root + 'plots/poly_chi2_hist_all_dof.png'

    py.savefig(outputFile)

    # ==========
    # Now histograms on the reduced-chi2
    # ==========
    # Plot the reduced distribution
    binSize = np.median(chi2Xred) / 10.0
    binsIn = np.arange(0, 100, binSize)
    binScale = 100.0
    binsInModel = np.arange(0, 100, binSize / binScale)
    chi2model = np.zeros(len(binsInModel), dtype=float)

    # Make a model distribution using the appropriate degrees of
    # freedom for all the stars.
    maxEpochCnt = cnt.max()
    minEpochCnt = cnt.min()

    for ii in range(minEpochCnt, maxEpochCnt + 1):
        idx = np.where(cnt == ii)[0]

        if len(idx) > 0:
            degreesOfFreedom = dof[idx[0]]
            chi2 = scipy.stats.chi2(degreesOfFreedom)

            # Get PDF, and then convert to histogram with the
            # Same prob/bin as our data histogram
            tmp = chi2.pdf(binsInModel * degreesOfFreedom)
            tmp *= len(idx) * binScale / tmp.sum()

            # Add to our model
            chi2model += tmp

    # Plot up the results
    py.clf()

    # X
    py.subplot(2, 1, 1)
    (n, bins, p) = py.hist(chi2Xred, bins=binsIn, alpha=0.6)
    p1 = py.plot(binsInModel, chi2model)
    py.xlim(0, 5)
    py.ylabel('Number of Stars')
    py.xlabel('X Velocity Fit Reduced Chi^2')
    py.title('%d stars in %d-%d Epochs' %
             (len(chi2Xred), cnt.min(), cnt.max()))

    # Y
    py.subplot(2, 1, 2)
    (n, bins, p) = py.hist(chi2Yred, bins=binsIn, alpha=0.6)
    p1 = py.plot(binsInModel, chi2model)
    py.xlim(0, 5)
    py.ylabel('Number of Stars')
    py.xlabel('Y Velocity Fit Reduced Chi^2')

    if trimMaxEpochs:
        outputFile = root + 'plots/poly_chi2red_hist_max_dof.png'
    else:
        outputFile = root + 'plots/poly_chi2red_hist_all_dof.png'

    py.savefig(outputFile)
Beispiel #24
0
def AlignModel(t0,
               beta,
               tau,
               i0,
               target,
               align,
               source_m=True,
               ang=0.0,
               mL=1.0,
               dL=4000.0,
               dS=8000.0,
               save_fig=False,
               outdir='./'):
    '''
    Compares a PSPL model based on input assumptions against aligned data.

    Args:
        t0 - float: Time of peak photometric signal in days (t=0 on New Year's of year 0, UTC).
        beta - float: Minimum angular distance between source and lens in mas.
        tau - float: Einstein crossing time in days.
        i0 - float: Base photometric magnitude.
        target - str: Name of the target.
        align - str: Path to the alignment directory.
        source_m - bool: Determine if either the source is the moving object (True) or the lens (False).
        ang - float: Angle (degrees) at which the moving object travels w.r.t. the ecliptic.
        mL - float: Mass of the lens in solar masses.
        dL - float: Distance to the lens in parsecs.
        dS - float: Distance to the source in parsecs.
        save_fig - bool: To save or not to save the figure.
        outdir - str: Path to save figure. Folder is created in outdir.
    '''
    test, modeled = assume(t0, beta, tau, i0, ang, mL, dL, dS, source_m)

    if save_fig == True:
        os.chdir(outdir)
        test_dir = (outdir + test)
        print('Saving in ' + test_dir)
        if os.path.exists(test_dir) == False:
            os.mkdir(test_dir)

    # get the aligned data
    s = starset.StarSet(align + 'align/align_t')
    s.loadPolyfit(align + 'polyfit_d/fit', accel=0, arcsec=0)

    names = s.getArray('name')
    ss = names.index(target)
    star = s.stars[ss]

    pointsTab = Table.read(align + 'points_d/' + target + '.points',
                           format='ascii')
    at = pointsTab[pointsTab.colnames[0]]
    ax = pointsTab[pointsTab.colnames[1]]
    ay = pointsTab[pointsTab.colnames[2]]
    axerr = pointsTab[pointsTab.colnames[3]]
    ayerr = pointsTab[pointsTab.colnames[4]]
    fitx = star.fitXv
    fity = star.fitYv

    mt = np.arange(t0 - 1500, t0 + 1500, 1)
    mdt = mt - modeled.t0
    adt = at - (modeled.t0 / 365.25)
    fdt = at - fitx.t0

    thE = modeled.thetaE_amp
    mshift = modeled.get_centroid_shift(mt)
    fitLineX = fitx.p + (fitx.v * fdt)
    fitSigX = np.sqrt(fitx.perr**2 + (fdt * fitx.verr)**2)
    fitLineY = fity.p + (fity.v * fdt)
    fitSigY = np.sqrt(fity.perr**2 + (fdt * fity.verr)**2)

    adt *= 365.25

    axf = (ax - fitLineX)
    ayf = (ay - fitLineY)

    ## plot everything scaled in Einstein units
    # x data
    alignment = align[-27:-1]
    fig = py.figure(figsize=(20, 10))
    xpl = py.subplot(211)
    py.plot(mdt / modeled.tE, mshift[:, 0] / thE, 'k-')
    py.errorbar(adt / modeled.tE,
                axf * 9.95 / thE,
                yerr=axerr * 9.95 / thE,
                fmt='ro')
    py.legend(['model (tE = %.2f days)' % (modeled.tE), alignment], loc=4)
    py.plot(adt / modeled.tE, fitSigX * 9.95 / thE, 'b--')
    py.plot(adt / modeled.tE, -fitSigX * 9.95 / thE, 'b--')
    xpl.set_ylabel(r'dX / $\theta_E$')
    py.title(test[1:-1] + r' - $\theta_E =$ %.2f [mas]' % thE)

    # y data
    ypl = py.subplot(212, sharex=xpl)
    py.subplots_adjust(hspace=0)
    py.plot(mdt / modeled.tE, mshift[:, 1] / thE, 'k-')
    py.plot(adt / modeled.tE, fitSigY * 9.95 / thE, 'b--')
    py.plot(adt / modeled.tE, -fitSigY * 9.95 / thE, 'b--')
    py.errorbar(adt / modeled.tE,
                ayf * 9.95 / thE,
                yerr=ayerr * 9.95 / thE,
                fmt='ro')
    ypl.set_ylabel(r'dY / $\theta_E$')
    ypl.set_xlabel('(t - t0) / tE')

    if save_fig == True:
        py.savefig(test_dir + 'shift_v_t.png')
    py.show()

    ## zoomed-in plot with residuals
    # approximate residual to integer model times
    madt = np.round(adt)
    xr = []
    yr = []
    for i in range(len(madt)):
        idx = np.where(mdt == madt[i])[0]
        xr.append(axf[i] * 9.95 - mshift[idx, 0])
        yr.append(ayf[i] * 9.95 - mshift[idx, 1])
    xr = np.array(xr)
    yr = np.array(yr)

    fig2, (xplz, xres, yplz,
           yres) = py.subplots(4,
                               1,
                               figsize=(15, 15),
                               gridspec_kw={'height_ratios': [3, 1, 3, 1]},
                               sharex=True)
    fig2.subplots_adjust(hspace=0)

    xplz.plot(mdt / modeled.tE, mshift[:, 0] / thE, 'k-')
    xplz.errorbar(adt / modeled.tE,
                  axf * 9.95 / thE,
                  yerr=axerr * 9.95 / thE,
                  fmt='ro')
    xplz.legend(['model (tE = %.2f days)' % (modeled.tE), alignment], loc=4)
    xplz.plot(adt / modeled.tE, fitSigX * 9.95 / thE, 'b--')
    xplz.plot(adt / modeled.tE, -fitSigX * 9.95 / thE, 'b--')
    xplz.set_ylabel(r'dX / $\theta_E$')
    xplz.set_title(test[1:-1] + r' - $\theta_E =$ %.2f [mas]' % thE)
    xres.errorbar(adt / modeled.tE,
                  xr / thE,
                  yerr=axerr * 9.95 / thE,
                  fmt='ro')
    xres.axhline(color='k')
    xres.set_ylabel('dX res')

    yplz.plot(mdt / modeled.tE, mshift[:, 1] / thE, 'k-')
    yplz.plot(adt / modeled.tE, fitSigY * 9.95 / thE, 'b--')
    yplz.plot(adt / modeled.tE, -fitSigY * 9.95 / thE, 'b--')
    yplz.errorbar(adt / modeled.tE,
                  ayf * 9.95 / thE,
                  yerr=ayerr * 9.95 / thE,
                  fmt='ro')
    yplz.set_xlim(
        [adt[0] / modeled.tE - 2, adt[len(adt) - 1] / modeled.tE + 2])
    yplz.set_ylabel(r'dY / $\theta_E$')
    yres.errorbar(adt / modeled.tE,
                  yr / thE,
                  yerr=ayerr * 9.95 / thE,
                  fmt='ro')
    yres.axhline(color='k')
    yres.set_ylabel('dY res')
    yres.set_xlabel('(t - t0) / tE')

    if save_fig == True:
        py.savefig(test_dir + 'shift_v_t_zoom.png')
    py.show()
Beispiel #25
0
def medianError(root='./',
                align='align/align_d_rms_t',
                poly='polyfit_d_points/fit',
                points='points_d/',
                youngOnly=False,
                adjustPoints=False):
    """
    Determine the median error in the Y direction for all stars
    during all epochs.
    """
    # Load up our starlist
    s = starset.StarSet(root + align)

    if (youngOnly):
        s.onlyYoungDisk()

    xerrAll = np.arange(0, float)
    yerrAll = np.arange(0, float)

    # We also want to get median errors for varioius
    # magnitude bins.
    err9_10 = np.arange(0, float)
    err10_11 = np.arange(0, float)
    err11_12 = np.arange(0, float)
    err12_13 = np.arange(0, float)
    err13_14 = np.arange(0, float)
    err14_15 = np.arange(0, float)

    for star in s.stars:
        pointsFile = root + points + star.name + '.points'

        pointsTab = asciidata.open(pointsFile)

        # Observed Data
        t = pointsTab[0].tonumpy()
        x = pointsTab[1].tonumpy()
        y = pointsTab[2].tonumpy()
        xerr = pointsTab[3].tonumpy()
        yerr = pointsTab[4].tonumpy()

        xerrAll = np.concatenate((xerrAll, xerr))
        yerrAll = np.concatenate((yerrAll, yerr))

        if (star.mag >= 9 and star.mag < 10):
            err9_10 = np.concatenate((err9_10, yerr))
        if (star.mag >= 10 and star.mag < 11):
            err10_11 = np.concatenate((err10_11, yerr))
        if (star.mag >= 11 and star.mag < 12):
            err11_12 = np.concatenate((err11_12, yerr))
        if (star.mag >= 12 and star.mag < 13):
            err12_13 = np.concatenate((err12_13, yerr))
        if (star.mag >= 13 and star.mag < 14):
            err13_14 = np.concatenate((err13_14, yerr))
        if (star.mag >= 14 and star.mag < 15):
            err14_15 = np.concatenate((err14_15, yerr))

    print 'Median X err: %7.4f (pix)' % np.median(xerrAll)
    print 'Median Y err: %7.4f (pix)' % np.median(yerrAll)

    mag = arange(9.5, 15, 1.0)
    medianMag = array([
        np.median(err9_10),
        np.median(err10_11),
        np.median(err11_12),
        np.median(err12_13),
        np.median(err13_14),
        np.median(err14_15)
    ])

    py.clf()
    py.plot(mag, medianMag, 'k^')
    py.xlabel('Magnitude')
    py.ylabel('Median Error (pix)')

    # Stars in K=11-12 bin seem to be well fit. So lets determine
    # the global scale parameter by adjusting the next lowest bin
    # up to that level
    sysErr = np.sqrt(medianMag[2]**2 - medianMag[1]**2) / 1.5
    #sysErr = 0.03

    print 'Systematic Error to be quad summed to Y: ', sysErr

    # --- The sysErr will be added in quadrature to everything.
    # --- Adjustment will only be made in the Y direction.

    if (adjustPoints):
        # Points adjustment must happen on ALL stars
        s = starset.StarSet(root + align)

        newPoints = points[:-1] + '_err/'
        print 'Adjusted points saved to ', newPoints

        for star in s.stars:
            oldPointsFile = root + points + star.name + '.points'
            newPointsFile = root + newPoints + star.name + '.points'

            pointsTab = asciidata.open(oldPointsFile)

            date = pointsTab[0].tonumpy()
            oldErrX = pointsTab[3].tonumpy()
            oldErrY = pointsTab[4].tonumpy()

            #newErrX = oldErrX
            newErrX = np.sqrt(oldErrX**2 + sysErr**2)
            newErrY = np.sqrt(oldErrY**2 + sysErr**2)

            for row in range(len(oldErrX)):
                pointsTab[3][row] = newErrX[row]
                pointsTab[4][row] = newErrY[row]

            # Temporarily delete AO epochs
            #pointsTab.delete(len(oldErrX) - 2)
            #pointsTab.delete(len(oldErrX) - 5)

            # Temporarily scale AO epochs
            #ao1 = len(oldErrX) - 2
            #pointsTab[3][ao1] = sqrt(oldErrX[ao1]**2 + 0.08**2)
            #pointsTab[4][ao1] = sqrt(oldErrY[ao1]**2 + 0.08**2)
            #ao2 = len(oldErrX) - 5
            #pointsTab[3][ao2] = sqrt(oldErrX[ao2]**2 + 0.08**2)
            #pointsTab[4][ao2] = sqrt(oldErrY[ao2]**2 + 0.08**2)

            pointsTab.writeto(newPointsFile)
def plot_vector_diff(undersample):
    """
    Make a vector plot of the differences between the input positions
    and the output positions after running starfinder.
    """
    # Dimensions of new grid
    npsf_side = get_npsf_side(undersample)
    suffix = '%d_%d' % (npsf_side, npsf_side)

    s = starset.StarSet('grid_' + suffix + '/align_' + suffix)

    cnt = s.getArray('velCnt')
    mag = s.getArray('mag')
    idx = np.where((cnt == 2) & (mag < 15))[0]
    print 'Using {0} stars out of {1}'.format(len(idx), len(cnt))

    newStars = [s.stars[ii] for ii in idx]
    s.stars = newStars

    x0 = s.getArrayFromEpoch(0, 'xorig')
    y0 = s.getArrayFromEpoch(0, 'yorig')
    x1 = s.getArrayFromEpoch(1, 'xorig')
    y1 = s.getArrayFromEpoch(1, 'yorig')

    dx = x1 - x0
    dy = y1 - y0
    dr = np.hypot(dx, dy)

    # Boundaries
    t = atpy.Table('svpar_' + suffix + '.txt', type='ascii')
    lx = t.col1
    ux = t.col2
    ly = t.col3
    uy = t.col4
    xedges = np.unique(np.append(lx, ux))
    yedges = np.unique(np.append(ly, uy))

    py.clf()
    q = py.quiver(x0, y0, dx, dy, scale=0.2)
    py.xlim(0, 1200)
    py.ylim(0, 1200)
    py.quiverkey(q,
                 0.5,
                 0.97,
                 0.02,
                 '0.02 pixel (0.2 mas)',
                 color='red',
                 coordinates='axes')

    for xx in xedges:
        py.axvline(xx, linestyle='--')
    for yy in yedges:
        py.axhline(yy, linestyle='--')

    py.savefig('plots/vec_diff_' + suffix + '.png')

    xmean = statsIter.mean(dx, hsigma=5, lsigma=5, iter=5)
    ymean = statsIter.mean(dy, hsigma=5, lsigma=5, iter=5)
    rmean = statsIter.mean(dr, hsigma=5, lsigma=5, iter=5)
    xstd = statsIter.std(dx, hsigma=5, lsigma=5, iter=5)
    ystd = statsIter.std(dy, hsigma=5, lsigma=5, iter=5)
    rstd = statsIter.std(dr, hsigma=5, lsigma=5, iter=5)
    print('Mean Delta-X: {0:9.5f} +/- {1:9.5f} pixels'.format(xmean, xstd))
    print('Mean Delta-Y: {0:9.5f} +/- {1:9.5f} pixels'.format(ymean, ystd))
    print('Mean Delta-R: {0:9.5f} +/- {1:9.5f} pixels'.format(rmean, rstd))
    f_name = 'diff_stats_' + suffix + '.txt'
    f_stat = open(f_name, 'w')
    hdr = '#{0:>5s} {1:>10s} {2:>10s} {3:>10s} {4:>10s} {5:>10s} {6:>10s}\n'
    fmt = '{0:6d} {1:10.5f} {2:10.5f} {3:10.5f} {4:10.5f} {5:10.5f} {6:10.5f}\n'
    f_stat.write(
        hdr.format('Npsf', 'Xmean', 'Ymean', 'Rmean', 'Xstd', 'Ystd', 'Rstd'))
    f_stat.write(fmt.format(npsf_side, xmean, ymean, rmean, xstd, ystd, rstd))
    f_stat.close()

    return f_name
Beispiel #27
0
def PhotoModel(t0,
               beta,
               tau,
               i0,
               stars,
               align,
               source_m=True,
               ang=0.0,
               mL=1.0,
               dL=4000.0,
               dS=8000.0,
               save_fig=False,
               outdir='./'):
    '''
    Creates a PSPL model based on input assumptions against aligned data.

    Args:
        t0 - float: Time of peak photometric signal in days (t=0 on New Year's of year 0, UTC).
        beta - float: Minimum angular distance between source and lens in mas.
        tau - float: Einstein crossing time in days.
        i0 - float: Base photometric magnitude.
        stars - str array: Array of stars.
        align - str: Path to the alignment directory.
        source_m - bool: Determine if either the source is the moving object (True) or the lens (False).
        ang - float: Angle (degrees) at which the moving object travels w.r.t. the ecliptic.
        mL - float: Mass of the lens in solar masses.
        dL - float: Distance to the lens in parsecs.
        dS - float: Distance to the source in parsecs.
        save_fig - bool: To save or not to save the figure.
        outdir - str: Path to save figure. Folder is created in outdir.
    '''
    test, modeled = assume(t0, beta, tau, i0, ang, mL, dL, dS, source_m)

    if save_fig == True:
        os.chdir(outdir)
        test_dir = (outdir + test)
        print('Saving in ' + test_dir)
        if os.path.exists(test_dir) == False:
            os.mkdir(test_dir)

    # get the model and aligned data
    s = starset.StarSet(align + 'align/align_t')
    s.loadPolyfit(align + 'polyfit_d/fit', accel=0, arcsec=0)

    # x = s.getArrayFromAllEpochs('xpix')
    # y = s.getArrayFromAllEpochs('ypix')
    # xe_p = s.getArrayFromAllEpochs('xpixerr_p')
    # ye_p = s.getArrayFromAllEpochs('ypixerr_p')

    N_epochs = len(s.years)
    mags = np.zeros([N_epochs, 3])
    mean_mag = np.zeros([3, 1])

    for i in range(len(stars)):
        photTab = Table.read(align + 'points_d/' + stars[i] + '.phot',
                             format='ascii')
        mags[:, i] = photTab[photTab.colnames[6]]
        if i == 0:
            m0 = photTab[photTab.colnames[6]]
        mean_mag[i] = np.mean(mags[:, i])
        mags[:, i] -= mean_mag[i]

    at = photTab[photTab.colnames[0]]
    mt = np.arange(t0 - 1500, t0 + 1500, 1)
    mdt = mt - modeled.t0
    adt = at - (modeled.t0 / 365.25)

    adt *= 365.25

    #get OGLE data
    ogle = Table.read(
        '/g/lu/microlens/cross_epoch/OB150211/OGLE-2015-BLG-0211.dat',
        format='ascii')
    ot = (ogle['col1'] - 1721057.5) / 365.25
    om = ogle['col2']
    omr = ogle['col3']

    # get the modeled photometry
    photo = modeled.get_photometry(at * 365.25)
    pdb.set_trace()
    fig1 = py.figure(figsize=(8, 8))
    py.errorbar(ot, om, yerr=omr, fmt='o')
    py.plot(at, photo, 'ko', at, m0 + 7.83, 'ro')
    py.gca().invert_yaxis()
    py.ylabel('mag')
    py.legend(['model', 'uncalibrated data + 7.83', 'OGLE O-IV optimized'])
    py.tight_layout()
    if save_fig:
        py.savefig(test_dir + 'model_phot.png')
    py.show()

    fig2 = py.figure(figsize=(8, 8))
    py.plot(at, mags[:, 0], 'ko', at, mags[:, 1], 'o', at, mags[:, 2], 'o')
    py.legend([stars[0], stars[1], stars[2]])
    py.ylabel(r'$\Delta$mag')
    py.tight_layout()
    if save_fig:
        py.savefig(test_dir + 'del_phot.png')
    py.show()

    return photo
Beispiel #28
0
def cdf(root='./',
        align='align/align_d_rms_t',
        poly='polyfit_d_points/fit',
        accel=False,
        youngOnly=False,
        trimMaxEpochs=True):

    s = starset.StarSet(root + align)
    s.loadPolyfit(root + poly, arcsec=1, accel=accel)

    if (youngOnly):
        s.onlyYoungDisk()

    if (accel):
        chi2Xred = s.getArray('fitXa.chi2red')
        chi2Yred = s.getArray('fitYa.chi2red')
        chi2X = s.getArray('fitXa.chi2')
        chi2Y = s.getArray('fitYa.chi2')
        dof = s.getArray('fitXa.dof')
    else:
        chi2Xred = s.getArray('fitXv.chi2red')
        chi2Yred = s.getArray('fitYv.chi2red')
        chi2X = s.getArray('fitXv.chi2')
        chi2Y = s.getArray('fitYv.chi2')
        dof = s.getArray('fitXv.dof')

    cnt = s.getArray('velCnt')

    if trimMaxEpochs:
        idx = np.where(cnt == cnt.max())[0]
        chi2Xred = chi2Xred[idx]
        chi2Yred = chi2Yred[idx]
        chi2X = chi2X[idx]
        chi2Y = chi2Y[idx]
        dof = dof[idx]
        cnt = cnt[idx]

    # Make a model distribution using the appropriate degrees of
    # freedom for all the stars.
    maxEpochCnt = cnt.max()
    minEpochCnt = cnt.min()

    # ==========
    # First analyze chi^2 (not reduced)
    # ==========
    chi2Xsorted = chi2X.copy()
    chi2Xsorted.sort()

    chi2Ysorted = chi2Y.copy()
    chi2Ysorted.sort()

    cdfObserved = (np.arange(len(chi2X)) + 1.) / len(chi2X)

    def cdfModel(chi2data):
        chi2model = np.zeros(len(chi2data), dtype=float)

        for ii in range(minEpochCnt, maxEpochCnt + 1):
            idx = np.where(cnt == ii)[0]

            if len(idx) > 0:
                degreesOfFreedom = dof[idx[0]]
                chi2 = scipy.stats.chi2(degreesOfFreedom)

                tmp = chi2.cdf(chi2data)
                tmp *= float(len(idx)) / len(chi2data)
                chi2model += tmp

        return chi2model

    chi2modelX = cdfModel(chi2Xsorted)
    chi2modelY = cdfModel(chi2Ysorted)

    foox = scipy.stats.kstest(chi2Xsorted, cdfModel)
    fooy = scipy.stats.kstest(chi2Ysorted, cdfModel)
    print foox, fooy
    print 'KS Test - Probability that observations follow expected distribution:'
    print '  X: D = %.2f   P = %e' % (foox[0], foox[1])
    print '  Y: D = %.2f   P = %e' % (fooy[0], fooy[1])

    # Plot up the results
    py.clf()

    # X
    py.subplot(2, 1, 1)
    py.plot(chi2Xsorted, cdfObserved, 'k-')
    py.plot(chi2Xsorted, chi2modelX, 'b-')
    py.xlim(0, dof[0] * 5)
    py.ylabel('CDF for X Vel. Fit')
    py.title('%d stars in %d-%d epochs' %
             (len(chi2Xred), cnt.min(), cnt.max()))

    # Y
    py.subplot(2, 1, 2)
    py.plot(chi2Ysorted, cdfObserved, 'k-')
    py.plot(chi2Ysorted, chi2modelY, 'b-')
    py.xlim(0, dof[0] * 5)
    py.ylabel('CDF for Y Vel. Fit')
    py.xlabel('Chi^2')
    py.legend(('Observed', 'Model'), loc='lower right')

    if trimMaxEpochs:
        outputFile = root + 'plots/poly_chi2_cdf_max_dof.png'
    else:
        outputFile = root + 'plots/poly_chi2_cdf_all_dof.png'

    py.savefig(outputFile)

    # ==========
    # Now analyze reduced chi^2
    # ==========
    chi2Xsorted = chi2Xred.copy()
    chi2Xsorted.sort()

    chi2Ysorted = chi2Yred.copy()
    chi2Ysorted.sort()

    cdfObserved = (np.arange(len(chi2Xred)) + 1.) / len(chi2Xred)

    def cdfModel(chi2data):
        # Here chi2data is a list of reduced chi2 values.
        chi2model = np.zeros(len(chi2data), dtype=float)

        for ii in range(minEpochCnt, maxEpochCnt + 1):
            idx = np.where(cnt == ii)[0]

            if len(idx) > 0:
                degreesOfFreedom = dof[idx[0]]
                chi2 = scipy.stats.chi2(degreesOfFreedom)

                tmp = chi2.cdf(chi2data * degreesOfFreedom)
                tmp *= float(len(idx)) / len(chi2data)
                chi2model += tmp

        return chi2model

    chi2modelX = cdfModel(chi2Xsorted)
    chi2modelY = cdfModel(chi2Ysorted)

    foox = scipy.stats.kstest(chi2Xsorted, cdfModel)
    fooy = scipy.stats.kstest(chi2Ysorted, cdfModel)
    print 'KS Test - Probability that observations follow expected distribution:'
    print '  X: D = %.2f   P = %e' % (foox[0], foox[1])
    print '  Y: D = %.2f   P = %e' % (fooy[0], fooy[1])

    # Plot up the results
    py.clf()

    # X
    py.subplot(2, 1, 1)
    py.plot(chi2Xsorted, cdfObserved, 'k-')
    py.plot(chi2Xsorted, chi2modelX, 'b-')
    py.xlim(0, 5)
    py.ylabel('CDF for X Vel. Fit')
    py.title('%d stars in %d-%d epochs' %
             (len(chi2Xred), cnt.min(), cnt.max()))

    # Y
    py.subplot(2, 1, 2)
    py.plot(chi2Ysorted, cdfObserved, 'k-')
    py.plot(chi2Ysorted, chi2modelY, 'b-')
    py.xlim(0, 5)
    py.ylabel('CDF for Y Vel. Fit')
    py.xlabel('Reduced Chi^2')
    py.legend(('Observed', 'Model'), loc='lower right')

    if trimMaxEpochs:
        outputFile = root + 'plots/poly_chi2red_cdf_max_dof.png'
    else:
        outputFile = root + 'plots/poly_chi2red_cdf_all_dof.png'

    py.savefig(outputFile)
def plot_3_targs():

    #name three objects
    targNames = ['ob140613', 'ob150211', 'ob150029']

    #object alignment directories
    an_dirs = [
        '/g/lu/microlens/cross_epoch/OB140613/a_2018_09_24/prop/',
        '/g/lu/microlens/cross_epoch/OB150211/a_2018_09_19/prop/',
        '/g/lu/microlens/cross_epoch/OB150029/a_2018_09_24/prop/'
    ]
    align_dirs = ['align/align_t', 'align/align_t', 'align/align_t']
    points_dirs = ['points_a/', 'points_d/', 'points_d/']
    poly_dirs = ['polyfit_a/fit', 'polyfit_d/fit', 'polyfit_d/fit']

    xlim = [1.2, 2.0, 1.5]
    ylim = [1.0, 7.0, 1.5]

    #Output file
    #filename = '/Users/jlu/doc/proposals/keck/uc/19A/plot_3_targs.png'
    filename = '/Users/jlu/plot_3_targs.png'
    #figsize = (15, 4.5)
    figsize = (10, 4.5)

    ps = 9.92

    py.close(1)
    py.figure(1, figsize=figsize)

    Ntarg = len(targNames) - 1
    for i in range(Ntarg):
        rootDir = an_dirs[i]
        starName = targNames[i]
        align = align_dirs[i]
        poly = poly_dirs[i]
        point = points_dirs[i]

        s = starset.StarSet(rootDir + align)
        s.loadPolyfit(rootDir + poly, accel=0, arcsec=0)

        names = s.getArray('name')
        mag = s.getArray('mag')
        x = s.getArray('x')
        y = s.getArray('y')

        ii = names.index(starName)
        star = s.stars[ii]

        pointsTab = Table.read(rootDir + point + starName + '.points',
                               format='ascii')

        time = pointsTab[pointsTab.colnames[0]]
        x = pointsTab[pointsTab.colnames[1]]
        y = pointsTab[pointsTab.colnames[2]]
        xerr = pointsTab[pointsTab.colnames[3]]
        yerr = pointsTab[pointsTab.colnames[4]]

        if i == 0:
            print('Doing MJD')
            idx_2015 = np.where(time <= 57387)
            idx_2016 = np.where((time > 57387) & (time <= 57753))
            idx_2017 = np.where((time > 57753) & (time <= 58118))
            idx_2018 = np.where((time > 58119) & (time <= 58484))
        else:
            idx_2015 = np.where(time < 2016)
            idx_2016 = np.where((time >= 2016) & (time < 2017))
            idx_2017 = np.where((time >= 2017) & (time < 2018))
            idx_2018 = np.where((time >= 2018) & (time < 2019))

        fitx = star.fitXv
        fity = star.fitYv
        dt = time - fitx.t0
        fitLineX = fitx.p + (fitx.v * dt)
        fitSigX = np.sqrt(fitx.perr**2 + (dt * fitx.verr)**2)

        fitLineY = fity.p + (fity.v * dt)
        fitSigY = np.sqrt(fity.perr**2 + (dt * fity.verr)**2)

        from matplotlib.ticker import FormatStrFormatter
        fmtX = FormatStrFormatter('%5i')
        fmtY = FormatStrFormatter('%6.2f')
        fontsize1 = 16

        # Convert everything into relative coordinates:
        x -= fitx.p
        y -= fity.p
        fitLineX -= fitx.p
        fitLineY -= fity.p

        # Change plate scale.
        x = x * ps * -1.0
        y = y * ps
        xerr *= ps
        yerr *= ps
        fitLineX = fitLineX * ps * -1.0
        fitLineY = fitLineY * ps
        fitSigX *= ps
        fitSigY *= ps

        paxes = py.subplot(1, Ntarg, i + 1)
        py.errorbar(x[idx_2015],
                    y[idx_2015],
                    xerr=xerr[idx_2015],
                    yerr=yerr[idx_2015],
                    fmt='r.',
                    label='2015')
        py.errorbar(x[idx_2016],
                    y[idx_2016],
                    xerr=xerr[idx_2016],
                    yerr=yerr[idx_2016],
                    fmt='g.',
                    label='2016')
        py.errorbar(x[idx_2017],
                    y[idx_2017],
                    xerr=xerr[idx_2017],
                    yerr=yerr[idx_2017],
                    fmt='b.',
                    label='2017')
        py.errorbar(x[idx_2018],
                    y[idx_2018],
                    xerr=xerr[idx_2018],
                    yerr=yerr[idx_2018],
                    fmt='c.',
                    label='2018')

        # if i==1:
        #     py.yticks(np.arange(np.min(y-yerr-0.1*ps), np.max(y+yerr+0.1*ps), 0.3*ps))
        #     py.xticks(np.arange(np.min(x-xerr-0.1*ps), np.max(x+xerr+0.1*ps), 0.25*ps))
        # else:
        #     py.yticks(np.arange(np.min(y-yerr-0.1*ps), np.max(y+yerr+0.1*ps), 0.15*ps))
        #     py.xticks(np.arange(np.min(x-xerr-0.1*ps), np.max(x+xerr+0.1*ps), 0.15*ps))
        paxes.tick_params(axis='both', which='major', labelsize=fontsize1)
        paxes.yaxis.set_major_formatter(FormatStrFormatter('%.2f'))
        paxes.xaxis.set_major_formatter(FormatStrFormatter('%.2f'))
        py.xlabel('X offset (mas)', fontsize=fontsize1)
        py.ylabel('Y offset (mas)', fontsize=fontsize1)
        py.plot(fitLineX, fitLineY, 'k-', label='_nolegend_')
        py.plot(fitLineX + fitSigX,
                fitLineY + fitSigY,
                'k--',
                label='_nolegend_')
        py.plot(fitLineX - fitSigX,
                fitLineY - fitSigY,
                'k--',
                label='_nolegend_')

        # Plot lines between observed point and the best fit value along the model line.
        for ee in range(len(time)):
            if ee in idx_2015[0].tolist():
                color_line = 'red'
            if ee in idx_2016[0].tolist():
                color_line = 'green'
            if ee in idx_2017[0].tolist():
                color_line = 'blue'
            if ee in idx_2018[0].tolist():
                color_line = 'cyan'

            py.plot([fitLineX[ee], x[ee]], [fitLineY[ee], y[ee]],
                    color=color_line,
                    linestyle='dashed',
                    alpha=0.8)

        py.axis([xlim[i], -xlim[i], -ylim[i], ylim[i]])

        py.title(starName.upper())
        if i == 0:
            py.legend(loc=1, fontsize=12)

    py.subplots_adjust(wspace=0.6,
                       hspace=0.6,
                       left=0.08,
                       bottom=0.05,
                       right=0.95,
                       top=0.90)
    py.tight_layout()
    py.show()
    py.savefig(filename)

    return
Beispiel #30
0
    def __init__(self, root, refSrc='S1-5', align='align/align_t',
                 imgRoot='/u/ghezgroup/data/gc/06maylgs1/clean/kp/'):

        self.root = root
        self.refSrc = refSrc
        self.align = align
        self.imgRoot = imgRoot

        # Read in the aligned cleaned images
        s = starset.StarSet(root + align)

        self.names = s.getArray('name')
        self.mag = s.getArray('mag')
        self.starCnt = len(s.stars)
        self.epochCnt = len(s.stars[0].e)

        # Also need coordinates relative to a bright star near
        # the center of the field (refSrc)
        rid = self.names.index(refSrc)

        # Read in the list of images used in the alignment
        listFile = open(root+align+'.list', 'r')
        self.files = []
        for line in listFile:
            _data = line.split()
            self.files.append(_data[0])

        # Get the Strehl, FWHM, and Wave front error for each image
        print "Reading Strehl File"
        strehlFile = open(imgRoot + 'irs33N.strehl', 'r')
        _frameno = []
        _strehl = []
        _wfe = []
        _fwhm = []
        for line in strehlFile:
            if (line.startswith("#")):
                continue

            _data = line.split()
            _frameno.append(_data[0])
            _strehl.append(float(_data[1]))
            _wfe.append(float(_data[2]))
            _fwhm.append(float(_data[3]))

        _strehl = np.array(_strehl)
        _wfe = np.array(_wfe)
        _fwhm = np.array(_fwhm)
        
        self.strehl = np.zeros(self.epochCnt, dtype=float)
        self.wfe = np.zeros(self.epochCnt, dtype=float)
        self.fwhm = np.zeros(self.epochCnt, dtype=float)
        self.elevation = np.zeros(self.epochCnt, dtype=float)
        self.darCoeff1 = np.zeros(self.epochCnt, dtype=float)
        self.darCoeff2 = np.zeros(self.epochCnt, dtype=float)
        self.airmass = np.zeros(self.epochCnt, dtype=float)
        self.parang = np.zeros(self.epochCnt, dtype=float)
        self.horizonX = np.zeros(self.epochCnt, dtype=float)
        self.horizonY = np.zeros(self.epochCnt, dtype=float)
        self.zenithX = np.zeros(self.epochCnt, dtype=float)
        self.zenithY = np.zeros(self.epochCnt, dtype=float)
        
        # Get the differential atmospheric refraction coefficients
        # assume all stars effective wavelengths are at 2.1 microns
        from gcwork import astrometry as ast
        (refA, refB) = ast.keckDARcoeffs(2.1)
        ast = None
        
        for ff in range(self.epochCnt):
            # Find the first instance of "/c"
            temp1 = self.files[ff].split('/')
            temp2 = temp1[-1].split('_')
            
            if (temp2[0].startswith('mag')):
                # This is a combo image. We don't have info about this file.
                # We should do this one last and adopt the average of
                # all values.
                self.strehl[ff] = None
                self.wfe[ff] = None
                self.fwhm[ff] = None

                self.files[ff] = imgRoot + '../../combo/' + \
                            '_'.join(temp2[0:-1]) + '.fits'
            else:
                # Find this file
                idx = _frameno.index(temp2[0] + '.fits')
                self.strehl[ff] = _strehl[idx]
                self.wfe[ff] = _wfe[idx]
                self.fwhm[ff] = _fwhm[idx]
                
                self.files[ff] = imgRoot + temp2[0] + '.fits'

            # Get header info
            hdr = pyfits.getheader(self.files[ff])

            effWave = hdr['EFFWAVE']
            self.elevation[ff] = hdr['EL']
            lamda = hdr['CENWAVE']
            self.airmass[ff] = hdr['AIRMASS']
            self.parang[ff] = hdr['PARANG']

            date = hdr['DATE-OBS'].split('-')
            year = int(date[0])
            month = int(date[1])
            day = int(date[2])
            
            utc = hdr['UTC'].split(':')
            hour = int(utc[0])
            minute = int(utc[1])
            second = int(math.floor(float(utc[2])))
            
            utc = datetime.datetime(year, month, day, hour, minute, second)
            utc2hst = datetime.timedelta(hours=-10)
            hst = utc + utc2hst
            
            from keckdar import dar
            (refA, refB) = dar.keckDARcoeffs(effWave, hst.year,
                                             hst.month, hst.day,
                                             hst.hour, hst.minute)
            dar = None

            tanz = math.tan(math.radians(90.0 - self.elevation[ff]))
            tmp = 1 + tanz**2
            self.darCoeff1[ff] = tmp * (refA + 3.0 * refB * tanz**2)
            self.darCoeff2[ff] = -tmp * (refA*tanz +
                                         3.0 * refB * (tanz + 2.0*tanz**3))
            
            # Lets determine the zenith and horizon unit vectors for
            # this image.
            pa = math.radians(self.parang[ff] + float(hdr['ROTPOSN']) -
                              float(hdr['INSTANGL']))
            self.zenithX[ff] = math.sin(pa)
            self.zenithY[ff] = -math.cos(pa)
            self.horizonX[ff] = math.cos(pa)
            self.horizonY[ff] = math.sin(pa)
            
        # Now for each star in each image, calculate the positional difference
        # between that star and the reference star.
        self.posx = np.zeros((self.starCnt, self.epochCnt), float)
        self.posy = np.zeros((self.starCnt, self.epochCnt), float)
        self.posh = np.zeros((self.starCnt, self.epochCnt), float)
        self.posz = np.zeros((self.starCnt, self.epochCnt), float)
        self.diffx = np.zeros((self.starCnt, self.epochCnt), float)
        self.diffy = np.zeros((self.starCnt, self.epochCnt), float)
        self.diffh = np.zeros((self.starCnt, self.epochCnt), float)
        self.diffz = np.zeros((self.starCnt, self.epochCnt), float)
        self.diffr = np.zeros((self.starCnt, self.epochCnt), float)
        self.difft = np.zeros((self.starCnt, self.epochCnt), float)
        self.dar = np.zeros((self.starCnt, self.epochCnt), dtype=float)
        self.diffDR = np.zeros((self.starCnt, self.epochCnt), float)
        self.hasData = np.zeros((self.starCnt, self.epochCnt))
        
        # Positions and Errors to some reference source.
        self.avgx = np.zeros(self.starCnt, float)
        self.avgy = np.zeros(self.starCnt, float)
        self.rmsx = np.zeros(self.starCnt, float)
        self.rmsy = np.zeros(self.starCnt, float)
        self.rmsr = np.zeros(self.starCnt, float)
        self.rmst = np.zeros(self.starCnt, float)
        self.rmsRarc = np.zeros(self.starCnt, float)
        self.rmsTarc = np.zeros(self.starCnt, float)
        self.r = np.zeros(self.starCnt, float)
        
        # Get the reference coordinates at each epoch
        refStar = s.stars[rid]
        refCooX = np.zeros(self.epochCnt, float)
        refCooY = np.zeros(self.epochCnt, float)
        for ee in range(self.epochCnt):
            refCooX[ee] = refStar.e[ee].xorig
            refCooY[ee] = refStar.e[ee].yorig
            
        # Now for every epoch, compute the offset from the mean
        for ss in range(self.starCnt):
            star = s.stars[ss]

            # Original pixel positions
            xpix = star.getArrayAllEpochs('xorig')
            ypix = star.getArrayAllEpochs('yorig')

            xarc = (xpix - refCooX) * 0.00996
            yarc = (ypix - refCooY) * 0.00996

            # Filter out epochs with nodata
            idx = (np.where((xpix > -999) & (refCooX > -999)))[0]
            xgood = xarc[idx]
            ygood = yarc[idx]

            # Calculate the values averaged over all epochs
            self.avgx[ss] = xgood.mean()
            self.avgy[ss] = ygood.mean()
            self.r[ss] = np.sqrt(self.avgx[ss]**2 + self.avgy[ss]**2)
            self.rmsx[ss] = xgood.std() * 1000.0
            self.rmsy[ss] = ygood.std() * 1000.0

            # Calculate the values independently for each epoch
            self.posx[ss] = xarc
            self.posy[ss] = yarc
            self.posh[ss] = (xarc * self.horizonX) + (yarc * self.horizonY)
            self.posz[ss] = (xarc * self.zenithX) + (yarc * self.zenithY)
            
            dx = (xarc - self.avgx[ss]) * 1000.0
            dy = (yarc - self.avgy[ss]) * 1000.0

            avgX = self.avgx[ss]
            avgY = self.avgy[ss]
            avgR = np.sqrt(avgX**2 + avgY**2)
        
            # Convert into zenith (Y) and horizon(X) coordinates
            self.diffx[ss] = dx
            self.diffy[ss] = dy
            self.diffh[ss] = (dx * self.horizonX) + (dy * self.horizonY)
            self.diffz[ss] = (dx * self.zenithX) + (dy * self.zenithY)
            self.diffr[ss] = ((dx * avgX) + (dy * avgY)) / avgR
            self.difft[ss] = ((dx * -avgY) + (dy * avgX)) / avgR

            self.hasData[ss,idx] += 1
            self.hasData[ss, 0] = 0   # Turn off the combo epoch

            # Compute the predicted differential atmospheric refraction
            # between this star and the reference star in each of the
            # observed images.
            deltaZ = self.posz[ss] / 206265.0
            deltaR = self.darCoeff1 * deltaZ
            deltaR += self.darCoeff2 * deltaZ * abs(deltaZ)
            deltaR *= 206265.0

            self.dar[ss] = deltaR

            avgDR = deltaR[idx].mean()
            self.diffDR[ss] = (deltaR - avgDR) * 1000.0


        savefile = '%s/tables/pairwise_wrt_%s.pickle' % \
                   (self.root, self.refSrc)
        
        _save = open(savefile, 'w')
        pickle.dump(self, _save)
        _save.close()