def make_completeness_table(loga_mag_file, matchup_files, filt_names=None):
    """
    Read in the output of KS2 (post processed with xym2mat and xym2bar)
    and match it up with the input planted stars.

    Input
    ---------
    loga_mag_file : string
        The name of the LOGA_MAGS.INPUT.fits file (produced by remake_loga_input()

    matchup_files : list
        A list of matchup files that corresponds to the filters in the LOGA file.
        The matchup files are assumed to be in the same order as the LOGA magnitude
        columns.
    """

    # Read files
    loga = atpy.Table(loga_mag_file)
    mat = [starlists.read_matchup(mat_file) for mat_file in matchup_files]

    # Figure out the number of filters... make sure the match in input/output
    num_filt = len(matchup_files)
    num_filt2 = len(loga.columns) - 3

    if num_filt != num_filt2:
        print('Filter mismatch: {0} in input, {1} in output'.format())
        return

    # First modify the column names in loga to reflect that these are
    # input values
    loga.rename_column('x', 'x_in')
    loga.rename_column('y', 'y_in')

    for ff in range(num_filt):
        print('Processing Filter #{0}'.format(ff+1))
        if filt_names != None:
            filt = '_{0}'.format(filt_names[ff])
        else:
            filt = '_{0}'.format(ff+1)

        # Rename the input magnitude columns
        old_col_name = 'm{0}'.format(ff+1)
        new_col_name = 'm_in' + filt
        loga.rename_column(old_col_name, new_col_name)

        # Add the new columns to the table for all of the output data.
        loga.add_column('x_out' + filt, mat[ff].x)
        loga.add_column('y_out' + filt, mat[ff].y)
        loga.add_column('m_out' + filt, mat[ff].m)
        loga.add_column('xe_out' + filt, mat[ff].xe)
        loga.add_column('ye_out' + filt, mat[ff].ye)
        loga.add_column('me_out' + filt, mat[ff].me)
    

    loga.table_name = ''
    outfile_name = os.path.dirname(loga_mag_file) + 'completeness_matched.fits'
    loga.write(outfile_name)

    return loga
示例#2
0
def make_completeness_table(loga_mag_file, matchup_files, filt_names=None):
    """
    Read in the output of KS2 (post processed with xym2mat and xym2bar)
    and match it up with the input planted stars.

    Input
    ---------
    loga_mag_file : string
        The name of the LOGA_MAGS.INPUT.fits file (produced by remake_loga_input()

    matchup_files : list
        A list of matchup files that corresponds to the filters in the LOGA file.
        The matchup files are assumed to be in the same order as the LOGA magnitude
        columns.
    """

    # Read files
    loga = atpy.Table(loga_mag_file)
    mat = [starlists.read_matchup(mat_file) for mat_file in matchup_files]

    # Figure out the number of filters... make sure the match in input/output
    num_filt = len(matchup_files)
    num_filt2 = len(loga.columns) - 3

    if num_filt != num_filt2:
        print('Filter mismatch: {0} in input, {1} in output'.format())
        return

    # First modify the column names in loga to reflect that these are
    # input values
    loga.rename_column('x', 'x_in')
    loga.rename_column('y', 'y_in')

    for ff in range(num_filt):
        print('Processing Filter #{0}'.format(ff + 1))
        if filt_names != None:
            filt = '_{0}'.format(filt_names[ff])
        else:
            filt = '_{0}'.format(ff + 1)

        # Rename the input magnitude columns
        old_col_name = 'm{0}'.format(ff + 1)
        new_col_name = 'm_in' + filt
        loga.rename_column(old_col_name, new_col_name)

        # Add the new columns to the table for all of the output data.
        loga.add_column('x_out' + filt, mat[ff].x)
        loga.add_column('y_out' + filt, mat[ff].y)
        loga.add_column('m_out' + filt, mat[ff].m)
        loga.add_column('xe_out' + filt, mat[ff].xe)
        loga.add_column('ye_out' + filt, mat[ff].ye)
        loga.add_column('me_out' + filt, mat[ff].me)

    loga.table_name = ''
    outfile_name = os.path.dirname(loga_mag_file) + 'completeness_matched.fits'
    loga.write(outfile_name)

    return loga
def combine_in_out_ks2(ks2_input_file, matchup_files, suffixes=None):
    """
    Read in a LOGA.INPUT file and the corresponding MATCHUP.XYMEEE files
    and cross-match them. They should already be the same length and the in same
    order.

    Inputs
    ------
    ks2_input_file -- the LOGA.INPUT file
    matchup_files -- a list of MATCHUP.XYMEEE files

    Optional Inputs
    ---------------
    suffixes -- a list (same length as matchup_files) 
    """

    final = atpy.Table()
    final.table_name = ''

    # Read in the input ks2 file
    inp = atpy.Table('LOGA.INPUT', type='ascii')

    final.add_column('name', inp.col17)
    final.add_column('x_in', inp.col1)
    final.add_column('y_in', inp.col2)

    for ff in range(len(matchup_files)):
        if suffixes == None:
            suf = '_{0}'.format(ff + 1)
        else:
            suf = '_' + suffixes[ff]

        f_in = 'col{0}'.format(18 + 4 * ff)
        m_in = -2.5 * np.log10(inp[f_in])

        final.add_column('m_in' + suf, m_in)

        match = starlists.read_matchup(matchup_files[ff])

        if len(match) != len(final):
            print 'Problem reading ' + matchup_files[
                ff] + ': incorrect file length'

        final.add_column('x_out' + suf, match.x)
        final.add_column('y_out' + suf, match.y)
        final.add_column('m_out' + suf, match.m)
        final.add_column('xe_out' + suf, match.xe)
        final.add_column('ye_out' + suf, match.ye)
        final.add_column('me_out' + suf, match.me)

    final.write('ks2_in_out_catalog.fits', overwrite=True)
def combine_in_out_ks2(ks2_input_file, matchup_files, suffixes=None):
    """
    Read in a LOGA.INPUT file and the corresponding MATCHUP.XYMEEE files
    and cross-match them. They should already be the same length and the in same
    order.

    Inputs
    ------
    ks2_input_file -- the LOGA.INPUT file
    matchup_files -- a list of MATCHUP.XYMEEE files

    Optional Inputs
    ---------------
    suffixes -- a list (same length as matchup_files) 
    """

    final = atpy.Table()
    final.table_name = ""

    # Read in the input ks2 file
    inp = atpy.Table("LOGA.INPUT", type="ascii")

    final.add_column("name", inp.col17)
    final.add_column("x_in", inp.col1)
    final.add_column("y_in", inp.col2)

    for ff in range(len(matchup_files)):
        if suffixes == None:
            suf = "_{0}".format(ff + 1)
        else:
            suf = "_" + suffixes[ff]

        f_in = "col{0}".format(18 + 4 * ff)
        m_in = -2.5 * np.log10(inp[f_in])

        final.add_column("m_in" + suf, m_in)

        match = starlists.read_matchup(matchup_files[ff])

        if len(match) != len(final):
            print "Problem reading " + matchup_files[ff] + ": incorrect file length"

        final.add_column("x_out" + suf, match.x)
        final.add_column("y_out" + suf, match.y)
        final.add_column("m_out" + suf, match.m)
        final.add_column("xe_out" + suf, match.xe)
        final.add_column("ye_out" + suf, match.ye)
        final.add_column("me_out" + suf, match.me)

    final.write("ks2_in_out_catalog.fits", overwrite=True)
示例#5
0
def plot_vpd_across_field(nside=4, interact=False):
    """
    Plot the VPD at different field positions so we can see if there are
    systematic discrepancies due to residual distortions.
    """
    # Read in matched and aligned star lists from the *.ref5 analysis.
    # Recall these data sets are in the F814W reference frame with a 50 mas plate scale.
    t2005 = starlists.read_matchup(workDir +
                                   '02.PMA/MATCHUP.XYMEEE.F814W.ref5')
    t2010 = starlists.read_matchup(workDir +
                                   '02.PMA/MATCHUP.XYMEEE.F125W.ref5')

    scale = 50.0  # mas per pixel

    # Trim down to only those stars that are detected in both epochs.
    # Also make cuts on astrometric/photometric errors, etc.
    # We only want the well measured stars in this analysis.
    perrLim814 = 1.0 / scale
    perrLim125 = 4.0 / scale
    merrLim814 = 0.05
    merrLim125 = 0.1

    cond = ((t2005.m != 0) & (t2010.m != 0) & (t2005.xe < perrLim814) &
            (t2005.ye < perrLim814) & (t2010.xe < perrLim125) &
            (t2010.ye < perrLim125) & (t2005.me < merrLim814) &
            (t2010.me < merrLim125))

    t2005 = t2005.where(cond)
    t2010 = t2010.where(cond)

    # Calculate proper motions
    dt = years['2010_F125W'] - years['2005_F814W']
    dx = t2010.x - t2005.x
    dy = t2010.y - t2005.y
    pmx = dx * scale / dt
    pmy = dy * scale / dt
    pm = np.hypot(pmx, pmy)

    t2005.add_column('pmx', pmx)
    t2005.add_column('pmy', pmy)
    t2005.add_column('pm', pm)

    # Divide up the region into N x N boxes and plot up the VPD for each.
    xlo = math.floor(t2005.x.min())
    xhi = math.ceil(t2005.x.max())
    ylo = math.floor(t2005.y.min())
    yhi = math.ceil(t2005.y.max())
    xboxsize = round((xhi - xlo) / nside)
    yboxsize = round((yhi - ylo) / nside)

    # Setup colors
    jet = py.get_cmap('jet')
    cNorm = colors.Normalize(vmin=0, vmax=nside**2)
    colorMap = py.cm.ScalarMappable(norm=cNorm, cmap=jet)

    # Save the average proper motions in each box
    pmx = np.zeros((nside, nside), dtype=float)
    pmy = np.zeros((nside, nside), dtype=float)
    pmxe = np.zeros((nside, nside), dtype=float)
    pmye = np.zeros((nside, nside), dtype=float)
    xcen = np.zeros((nside, nside), dtype=float)
    ycen = np.zeros((nside, nside), dtype=float)

    pmCut = 1.0

    # Calculate the global mean proper motion
    # Start by trimming down to a 1 mas/yr radius
    idx2 = np.where(pm < pmCut)[0]
    pmx_all = np.median(t2005.pmx[idx2])
    pmy_all = np.median(t2005.pmy[idx2])

    out = 'All X:{0:5.0f}-{1:5.0f}  Y:{2:5.0f}-{3:5.0f}  '
    out += 'PMX:{4:5.2f} +/- {5:5.2f} PMY:{6:5.2f} +/- {7:5.2f}  '
    out += 'N:{8:5d}'
    print((out.format(xlo, xhi, ylo, yhi, pmx_all, 0.0, pmy_all, 0.0,
                      len(idx2))))

    # Make a global proper motion diagram of star with a proper motion within
    # 1 mas/yr. This is mainly to see systematic flows due to residual distortion.
    pmTot = np.hypot(t2005.pmx, t2005.pmy)
    clust = np.where(pmTot < pmCut)[0]
    py.clf()
    q = py.quiver(t2005.x[clust],
                  t2005.y[clust],
                  t2005.pmx[clust],
                  t2005.pmy[clust],
                  scale=18)
    py.quiverkey(q, 0.5, 0.98, 1, '1 mas/yr', color='red', labelcolor='red')
    py.xlabel('X Position (pixels)')
    py.ylabel('Y Position (pixels)')
    py.xlim(xlo, xhi)
    py.ylim(ylo, yhi)
    out = '{0}/plots/vec_proper_motion_all.png'
    py.savefig(out.format(workDir))

    py.clf()
    for xx in range(nside):
        for yy in range(nside):
            xlo_box = xlo + xx * xboxsize
            ylo_box = ylo + yy * yboxsize
            xhi_box = xlo + (1 + xx) * xboxsize
            yhi_box = ylo + (1 + yy) * yboxsize

            idx = np.where((t2005.x > xlo_box) & (t2005.x <= xhi_box)
                           & (t2005.y > ylo_box) & (t2005.y <= yhi_box))[0]

            if interact:
                color = colorMap.to_rgba(yy + xx * nside)
                lim = 5

                py.plot(t2005.pmx[idx],
                        t2005.pmy[idx],
                        'k.',
                        ms=2,
                        color=color)
                py.axis([-lim, lim, -lim, lim])

                py.xlabel('X Proper Motion (mas/yr)')
                py.ylabel('Y Proper Motion (mas/yr)')

            # Lets get the mean and std-dev (iterative) for the box.
            # Start by trimming down to a 1 mas/yr circle.
            idx2 = np.where(t2005.pm[idx] < pmCut)[0]
            xmean = np.median(t2005.pmx[idx][idx2])
            ymean = np.median(t2005.pmy[idx][idx2])
            xstd = t2005.pmx[idx][idx2].std()
            ystd = t2005.pmy[idx][idx2].std()
            xmean_err = xstd / np.sqrt(len(idx2))
            ymean_err = ystd / np.sqrt(len(idx2))

            xcen[xx, yy] = xlo_box + (xboxsize / 2.0)
            ycen[xx, yy] = ylo_box + (yboxsize / 2.0)
            pmx[xx, yy] = xmean - pmx_all
            pmy[xx, yy] = ymean - pmx_all
            pmxe[xx, yy] = xmean_err
            pmye[xx, yy] = ymean_err

            out = 'Box X:{0:5.0f}-{1:5.0f}  Y:{2:5.0f}-{3:5.0f}  '
            out += 'PMX:{4:5.2f} +/- {5:5.2f} PMY:{6:5.2f} +/- {7:5.2f}  '
            out += 'N:{8:5d}  '

            if interact:
                out += 'Continue?'
                input(
                    out.format(xlo_box, xhi_box, ylo_box, yhi_box, xmean,
                               xmean_err, ymean, ymean_err, len(idx2)))
            else:
                print((out.format(xlo_box, xhi_box, ylo_box, yhi_box, xmean,
                                  xmean_err, ymean, ymean_err, len(idx2))))

    if interact:
        out = '{0}/plots/vpd_grid_nside{1}.png'
        py.savefig(out.format(workDir, nside))

    py.clf()
    q = py.quiver(xcen, ycen, pmx, pmy)
    py.quiverkey(q,
                 0.5,
                 0.98,
                 0.1,
                 '0.1 mas/yr',
                 color='red',
                 labelcolor='red')
    py.xlabel('X Position (pixels)')
    py.ylabel('Y Position (pixels)')
    py.xlim(xlo, xhi)
    py.ylim(ylo, yhi)
    for xx in range(nside + 1):
        py.axvline(xlo + xx * xboxsize, linestyle='--', color='grey')
    for yy in range(nside + 1):
        py.axhline(ylo + yy * yboxsize, linestyle='--', color='grey')
    out = '{0}/plots/vec_proper_motion_grid_nside{1}.png'
    py.savefig(out.format(workDir, nside))

    py.clf()
    q = py.quiver(xcen, ycen, pmx / pmxe, pmy / pmye)
    py.quiverkey(q, 0.5, 0.98, 3, '3 sigma', color='red', labelcolor='red')
    py.xlabel('X Position (pixels)')
    py.ylabel('Y Position (pixels)')
    py.xlim(xlo, xhi)
    py.ylim(ylo, yhi)
    for xx in range(nside + 1):
        py.axvline(xlo + xx * xboxsize, linestyle='--', color='grey')
    for yy in range(nside + 1):
        py.axhline(ylo + yy * yboxsize, linestyle='--', color='grey')
    out = '{0}/plots/vec_proper_motion_grid_sig_nside{1}.png'
    py.savefig(out.format(workDir, nside))
示例#6
0
def make_master_lists():
    """
    Trim the ref5 master lists for each filter down to just stars with
    proper motions within 1 mas/yr of the cluster motion.
    """
    # Read in matched and aligned star lists from the *.ref5 analysis.
    # Recall these data sets are in the F814W reference frame with a 50 mas plate scale.
    t2005_814 = starlists.read_matchup(workDir +
                                       '02.PMA/MATCHUP.XYMEEE.F814W.ref5')
    t2010_125 = starlists.read_matchup(workDir +
                                       '02.PMA/MATCHUP.XYMEEE.F125W.ref5')
    t2010_139 = starlists.read_matchup(workDir +
                                       '02.PMA/MATCHUP.XYMEEE.F139M.ref5')
    t2010_160 = starlists.read_matchup(workDir +
                                       '02.PMA/MATCHUP.XYMEEE.F160W.ref5')

    scale = 50.0  # mas per pixel

    # Trim down to only those stars that are detected in both epochs.
    # Also make cuts on astrometric/photometric errors, etc.
    # We only want the well measured stars in this analysis.
    perrLim814 = 1.0 / scale
    perrLim125 = 4.0 / scale
    merrLim814 = 0.05
    merrLim125 = 0.1

    cond = ((t2005_814.m != 0) & (t2010_125.m != 0) & (t2010_139.m != 0) &
            (t2010_160.m != 0) & (t2005_814.xe < perrLim814) &
            (t2005_814.ye < perrLim814) & (t2010_125.xe < perrLim125) &
            (t2010_125.ye < perrLim125) & (t2010_139.xe < perrLim125) &
            (t2010_139.ye < perrLim125) & (t2010_160.xe < perrLim125) &
            (t2010_160.ye < perrLim125) & (t2005_814.me < merrLim814) &
            (t2010_125.me < merrLim125) & (t2010_139.me < merrLim125) &
            (t2010_160.me < merrLim125))

    t2005_814 = t2005_814.where(cond)
    t2010_125 = t2010_125.where(cond)
    t2010_139 = t2010_139.where(cond)
    t2010_160 = t2010_160.where(cond)

    # Calculate proper motions
    dt = years['2010_F125W'] - years['2005_F814W']
    dx = t2010_125.x - t2005_814.x
    dy = t2010_125.y - t2005_814.y
    pmx = dx * scale / dt
    pmy = dy * scale / dt
    pm = np.hypot(pmx, pmy)

    t2005_814.add_column('pmx', pmx)
    t2005_814.add_column('pmy', pmy)
    t2005_814.add_column('pm', pm)

    # Trim down to a 1 mas/yr radius
    pmCut = 1.0
    idx2 = np.where(pm < pmCut)[0]

    t2005_814 = t2005_814.where(idx2)
    t2010_125 = t2010_125.where(idx2)
    t2010_139 = t2010_139.where(idx2)
    t2010_160 = t2010_160.where(idx2)

    _o814 = open(workDir + '02.PMA/MASTER.F814W.ref5', 'w')
    _o125 = open(workDir + '02.PMA/MASTER.F125W.ref5', 'w')
    _o139 = open(workDir + '02.PMA/MASTER.F139M.ref5', 'w')
    _o160 = open(workDir + '02.PMA/MASTER.F160W.ref5', 'w')

    ofmt = '{0:10.4f} {1:10.4f} {2:8.4f} {3:10.4f} {4:10.4f} {5:8.4f} {6}\n'
    for ii in range(len(t2005_814)):
        _o814.write(
            ofmt.format(t2005_814.x[ii], t2005_814.y[ii], t2005_814.m[ii],
                        t2005_814.xe[ii], t2005_814.ye[ii], t2005_814.me[ii],
                        t2005_814.name[ii]))
        _o125.write(
            ofmt.format(t2010_125.x[ii], t2010_125.y[ii], t2010_125.m[ii],
                        t2010_125.xe[ii], t2010_125.ye[ii], t2010_125.me[ii],
                        t2010_125.name[ii]))
        _o139.write(
            ofmt.format(t2010_139.x[ii], t2010_139.y[ii], t2010_139.m[ii],
                        t2010_139.xe[ii], t2010_139.ye[ii], t2010_139.me[ii],
                        t2010_139.name[ii]))
        _o160.write(
            ofmt.format(t2010_160.x[ii], t2010_160.y[ii], t2010_160.m[ii],
                        t2010_160.xe[ii], t2010_160.ye[ii], t2010_160.me[ii],
                        t2010_160.name[ii]))

    _o814.close()
    _o125.close()
    _o139.close()
    _o160.close()
示例#7
0
def make_residuals_table_year_pos(year, filt, pos):
    year = str(year) 
    
    dir_xym = year + '_' + filt + '_' + pos + '/01.XYM/'

    # Read in the matchup file with the final positions and errors.
    stars = starlists.read_matchup(dir_xym + 'MATCHUP.XYMEEE.ref1')

    # For each image, read in the raw pixel coordinates, the transformed 
    # coordinates, and the residual offsets.
    N_images = len(imgs[year][filt][pos])
    N_stars = len(stars)

    xraw = np.zeros([N_images, N_stars])
    yraw = np.zeros([N_images, N_stars])
    mraw = np.zeros([N_images, N_stars])

    xt = np.zeros([N_images, N_stars])
    yt = np.zeros([N_images, N_stars])
    mt = np.zeros([N_images, N_stars])

    dx = np.zeros([N_images, N_stars])
    dy = np.zeros([N_images, N_stars])

    
    for nn in range(N_images):
        print 'nn = ', nn
        dat = ascii.read('{0:s}LNK.{1:03d}'.format(dir_xym, nn+1))

        xt[nn, :] = dat['col1']
        yt[nn, :] = dat['col2']
        mt[nn, :] = dat['col3']

        xraw[nn, :] = dat['col4']
        yraw[nn, :] = dat['col5']
        mraw[nn, :] = dat['col6']

        dx[nn, :] = dat['col7']
        dy[nn, :] = dat['col8']
        

    idx = np.where((stars['m']>-11) & (stars['m']<-6) & 
                   (stars['xe']<0.05) & (stars['ye']<0.05) & 
                   (stars['me']<0.1))[0]

    stars = stars[idx]
    xraw = xraw[:, idx]
    yraw = yraw[:, idx]
    mraw = mraw[:, idx]
    xt = xt[:, idx]
    yt = yt[:, idx]
    mt = mt[:, idx]
    dx = dx[:, idx]
    dy = dy[:, idx]
    xmean = xt.mean(axis=0)
    ymean = yt.mean(axis=0)
    mmean = mt.mean(axis=0)
    xstd = xt.std(axis=0)
    ystd = yt.std(axis=0)
    mstd = mt.std(axis=0)

    _out = open(dir_xym + 'resid_all_images.pickle', 'w')

    pickle.dump(stars, _out)
    pickle.dump(xmean, _out)
    pickle.dump(ymean, _out)
    pickle.dump(mmean, _out)
    pickle.dump(xstd, _out)
    pickle.dump(ystd, _out)
    pickle.dump(mstd, _out)
    pickle.dump(xraw, _out)
    pickle.dump(yraw, _out)
    pickle.dump(mraw, _out)
    pickle.dump(xt, _out)
    pickle.dump(yt, _out)
    pickle.dump(mt, _out)
    pickle.dump(dx, _out)
    pickle.dump(dy, _out)

    _out.close()
示例#8
0
def make_residuals_table_year_2pos(year, filt, pos1, pos2):
    year = str(year)

    dir_xym = year + '_' + filt + '/01.XYM/'

    
    # Read in the matchup file with the final positions and errors.
    stars = starlists.read_matchup(dir_xym + 'MATCHUP.XYMEEE.ref4')

    # For each image, read in the raw pixel coordinates, the transformed 
    # coordinates, and the residual offsets.
    N_images = len(imgs[year][filt][pos1])
    N_stars = len(stars)

    pos1_idx = get_file_indices(year, filt, pos1)
    pos2_idx = get_file_indices(year, filt, pos2)
    pos_idx = np.array([pos1_idx, pos2_idx])

    xraw = np.zeros([2, N_images, N_stars])
    yraw = np.zeros([2, N_images, N_stars])
    mraw = np.zeros([2, N_images, N_stars])

    xt = np.zeros([2, N_images, N_stars])
    yt = np.zeros([2, N_images, N_stars])
    mt = np.zeros([2, N_images, N_stars])

    dx = np.zeros([2, N_images, N_stars])
    dy = np.zeros([2, N_images, N_stars])

    detected = np.zeros([2, N_images, N_stars], dtype=bool)

    # Loop through images at each position
    for nn in range(N_images):
        # Loop through 2 different positions.
        for ii in range(2):
            print 'nn = ', nn, 'ii = ', ii

            dat = ascii.read('{0:s}LNK.{1:03d}'.format(dir_xym, pos_idx[ii, nn]))

            xt[ii, nn, :] = dat['col1'].data
            yt[ii, nn, :] = dat['col2'].data
            mt[ii, nn, :] = dat['col3'].data

            xraw[ii, nn, :] = dat['col4'].data
            yraw[ii, nn, :] = dat['col5'].data
            mraw[ii, nn, :] = dat['col6'].data

            dx[ii, nn, :] = dat['col7'].data
            dy[ii, nn, :] = dat['col8'].data

            idx = np.where(dat['col3'].data != 0)[0]
            detected[ii, nn, idx] = True
        
    # Trim the data down to those stars detected in ALL 
    # the images (the overlaps) at these two positions.
    det_Nimg = detected.sum(axis=1).sum(axis=0)
    idx = np.where(det_Nimg == (2*N_images))[0]
    print 'Trim 1', len(idx)

    xt = xt[:, :, idx]
    yt = yt[:, :, idx]
    mt = mt[:, :, idx]
    xraw = xraw[:, :, idx]
    yraw = yraw[:, :, idx]
    mraw = mraw[:, :, idx]
    dx = dx[:, :, idx]
    dy = dy[:, :, idx]
    detected = detected[:, :, idx]
    stars = stars[idx]

    # Also trim on some quality metrics.
    idx2 = np.where((stars['m']>-11) & (stars['m']<-6) & 
                   (stars['xe']<0.05) & (stars['ye']<0.05) & 
                   (stars['me']<0.1))[0]
    print 'Trim 1', len(idx2)

    stars = stars[idx2]
    xraw = xraw[:, :, idx2]
    yraw = yraw[:, :, idx2]
    mraw = mraw[:, :, idx2]
    xt = xt[:, :, idx2]
    yt = yt[:, :, idx2]
    mt = mt[:, :, idx2]
    dx = dx[:, :, idx2]
    dy = dy[:, :, idx2]
    xmean_p = xt.mean(axis=1)
    ymean_p = yt.mean(axis=1)
    mmean_p = mt.mean(axis=1)
    xstd_p = xt.std(axis=1)
    ystd_p = yt.std(axis=1)
    mstd_p = mt.std(axis=1)
    xmean = xmean_p.mean(axis=0)
    ymean = ymean_p.mean(axis=0)
    mmean = mmean_p.mean(axis=0)

    _out = open(dir_xym + 'resid_' + pos1 + '_' + pos2 + '.pickle', 'w')

    pickle.dump(stars, _out)
    pickle.dump(xmean, _out)
    pickle.dump(ymean, _out)
    pickle.dump(mmean, _out)
    pickle.dump(xmean_p, _out)
    pickle.dump(ymean_p, _out)
    pickle.dump(mmean_p, _out)
    pickle.dump(xstd_p, _out)
    pickle.dump(ystd_p, _out)
    pickle.dump(mstd_p, _out)
    pickle.dump(xraw, _out)
    pickle.dump(yraw, _out)
    pickle.dump(mraw, _out)
    pickle.dump(xt, _out)
    pickle.dump(yt, _out)
    pickle.dump(mt, _out)
    pickle.dump(dx, _out)
    pickle.dump(dy, _out)

    _out.close()
def plot_vpd_across_field(nside=4, interact=False):
    """
    Plot the VPD at different field positions so we can see if there are
    systematic discrepancies due to residual distortions.
    """
    # Read in matched and aligned star lists from the *.ref5 analysis.
    # Recall these data sets are in the F814W reference frame with a 50 mas plate scale.
    t2005 = starlists.read_matchup(workDir + '02.PMA/MATCHUP.XYMEEE.F814W.ref5')
    t2010 = starlists.read_matchup(workDir + '02.PMA/MATCHUP.XYMEEE.F125W.ref5')

    scale = 50.0 # mas per pixel
    

    # Trim down to only those stars that are detected in both epochs.
    # Also make cuts on astrometric/photometric errors, etc.
    # We only want the well measured stars in this analysis.
    perrLim814 = 1.0 / scale
    perrLim125 = 4.0 / scale
    merrLim814 = 0.05
    merrLim125 = 0.1
    
    cond = ((t2005.m != 0) & (t2010.m != 0) &
            (t2005.xe < perrLim814) & (t2005.ye < perrLim814) &
            (t2010.xe < perrLim125) & (t2010.ye < perrLim125) &
            (t2005.me < merrLim814) & (t2010.me < merrLim125))

    t2005 = t2005.where(cond)
    t2010 = t2010.where(cond)

    # Calculate proper motions
    dt = years['2010_F125W'] - years['2005_F814W']
    dx = t2010.x - t2005.x
    dy = t2010.y - t2005.y
    pmx = dx * scale / dt
    pmy = dy * scale / dt
    pm = np.hypot(pmx, pmy)

    t2005.add_column('pmx', pmx)
    t2005.add_column('pmy', pmy)
    t2005.add_column('pm', pm)


    # Divide up the region into N x N boxes and plot up the VPD for each.
    xlo = math.floor(t2005.x.min())
    xhi = math.ceil(t2005.x.max())
    ylo = math.floor(t2005.y.min())
    yhi = math.ceil(t2005.y.max())
    xboxsize = round((xhi - xlo) / nside)
    yboxsize = round((yhi - ylo) / nside)

    # Setup colors
    jet = py.get_cmap('jet')
    cNorm = colors.Normalize(vmin=0, vmax=nside**2)
    colorMap = py.cm.ScalarMappable(norm=cNorm, cmap=jet)

    # Save the average proper motions in each box
    pmx = np.zeros((nside, nside), dtype=float)
    pmy = np.zeros((nside, nside), dtype=float)
    pmxe = np.zeros((nside, nside), dtype=float)
    pmye = np.zeros((nside, nside), dtype=float)
    xcen = np.zeros((nside, nside), dtype=float)
    ycen = np.zeros((nside, nside), dtype=float)

    pmCut = 1.0

    # Calculate the global mean proper motion
    # Start by trimming down to a 1 mas/yr radius
    idx2 = np.where(pm < pmCut)[0]
    pmx_all = np.median( t2005.pmx[idx2] )
    pmy_all = np.median( t2005.pmy[idx2] )
    
    out = 'All X:{0:5.0f}-{1:5.0f}  Y:{2:5.0f}-{3:5.0f}  '
    out += 'PMX:{4:5.2f} +/- {5:5.2f} PMY:{6:5.2f} +/- {7:5.2f}  '
    out += 'N:{8:5d}'
    print((out.format(xlo, xhi, ylo, yhi, pmx_all, 0.0, pmy_all, 0.0, len(idx2))))

    # Make a global proper motion diagram of star with a proper motion within
    # 1 mas/yr. This is mainly to see systematic flows due to residual distortion.
    pmTot = np.hypot(t2005.pmx, t2005.pmy)
    clust = np.where(pmTot < pmCut)[0]
    py.clf()
    q = py.quiver(t2005.x[clust], t2005.y[clust], t2005.pmx[clust], t2005.pmy[clust],
                  scale=18)
    py.quiverkey(q, 0.5, 0.98, 1, '1 mas/yr', color='red', labelcolor='red')
    py.xlabel('X Position (pixels)')
    py.ylabel('Y Position (pixels)')
    py.xlim(xlo, xhi)
    py.ylim(ylo, yhi)
    out = '{0}/plots/vec_proper_motion_all.png'
    py.savefig(out.format(workDir))
    
    py.clf()
    for xx in range(nside):
        for yy in range(nside):
            xlo_box = xlo + xx * xboxsize
            ylo_box = ylo + yy * yboxsize
            xhi_box = xlo + (1+xx) * xboxsize
            yhi_box = ylo + (1+yy) * yboxsize

            idx = np.where((t2005.x > xlo_box) & (t2005.x <= xhi_box) &
                           (t2005.y > ylo_box) & (t2005.y <= yhi_box))[0]


            if interact:
                color = colorMap.to_rgba(yy + xx * nside)
                lim = 5

                py.plot(t2005.pmx[idx], t2005.pmy[idx], 'k.', ms=2, color=color)
                py.axis([-lim, lim, -lim, lim])

                py.xlabel('X Proper Motion (mas/yr)')
                py.ylabel('Y Proper Motion (mas/yr)')

            # Lets get the mean and std-dev (iterative) for the box.
            # Start by trimming down to a 1 mas/yr circle.
            idx2 = np.where(t2005.pm[idx] < pmCut)[0]
            xmean = np.median( t2005.pmx[idx][idx2] )
            ymean = np.median( t2005.pmy[idx][idx2] )
            xstd = t2005.pmx[idx][idx2].std()
            ystd = t2005.pmy[idx][idx2].std()
            xmean_err = xstd / np.sqrt(len(idx2))
            ymean_err = ystd / np.sqrt(len(idx2))

            xcen[xx, yy] = xlo_box + (xboxsize / 2.0)
            ycen[xx, yy] = ylo_box + (yboxsize / 2.0)
            pmx[xx, yy] = xmean - pmx_all
            pmy[xx, yy] = ymean - pmx_all
            pmxe[xx, yy] = xmean_err
            pmye[xx, yy] = ymean_err

            out = 'Box X:{0:5.0f}-{1:5.0f}  Y:{2:5.0f}-{3:5.0f}  '
            out += 'PMX:{4:5.2f} +/- {5:5.2f} PMY:{6:5.2f} +/- {7:5.2f}  '
            out += 'N:{8:5d}  '

            if interact:
                out += 'Continue?'
                input(out.format(xlo_box, xhi_box, ylo_box, yhi_box,
                                     xmean, xmean_err, ymean, ymean_err, len(idx2)))
            else:
                print((out.format(xlo_box, xhi_box, ylo_box, yhi_box,
                                 xmean, xmean_err, ymean, ymean_err, len(idx2))))


    if interact:
        out = '{0}/plots/vpd_grid_nside{1}.png'
        py.savefig(out.format(workDir, nside))

    py.clf()
    q = py.quiver(xcen, ycen, pmx, pmy)
    py.quiverkey(q, 0.5, 0.98, 0.1, '0.1 mas/yr', color='red', labelcolor='red')
    py.xlabel('X Position (pixels)')
    py.ylabel('Y Position (pixels)')
    py.xlim(xlo, xhi)
    py.ylim(ylo, yhi)
    for xx in range(nside+1):
        py.axvline(xlo + xx * xboxsize, linestyle='--', color='grey')
    for yy in range(nside+1):
        py.axhline(ylo + yy * yboxsize, linestyle='--', color='grey')
    out = '{0}/plots/vec_proper_motion_grid_nside{1}.png'
    py.savefig(out.format(workDir, nside))

    py.clf()
    q = py.quiver(xcen, ycen, pmx/pmxe, pmy/pmye)
    py.quiverkey(q, 0.5, 0.98, 3, '3 sigma', color='red', labelcolor='red')
    py.xlabel('X Position (pixels)')
    py.ylabel('Y Position (pixels)')
    py.xlim(xlo, xhi)
    py.ylim(ylo, yhi)
    for xx in range(nside+1):
        py.axvline(xlo + xx * xboxsize, linestyle='--', color='grey')
    for yy in range(nside+1):
        py.axhline(ylo + yy * yboxsize, linestyle='--', color='grey')
    out = '{0}/plots/vec_proper_motion_grid_sig_nside{1}.png'
    py.savefig(out.format(workDir, nside))
def make_master_lists():
    """
    Trim the ref5 master lists for each filter down to just stars with
    proper motions within 1 mas/yr of the cluster motion.
    """
    # Read in matched and aligned star lists from the *.ref5 analysis.
    # Recall these data sets are in the F814W reference frame with a 50 mas plate scale.
    t2005_814 = starlists.read_matchup(workDir + '02.PMA/MATCHUP.XYMEEE.F814W.ref5')
    t2010_125 = starlists.read_matchup(workDir + '02.PMA/MATCHUP.XYMEEE.F125W.ref5')
    t2010_139 = starlists.read_matchup(workDir + '02.PMA/MATCHUP.XYMEEE.F139M.ref5')
    t2010_160 = starlists.read_matchup(workDir + '02.PMA/MATCHUP.XYMEEE.F160W.ref5')

    scale = 50.0 # mas per pixel

    # Trim down to only those stars that are detected in both epochs.
    # Also make cuts on astrometric/photometric errors, etc.
    # We only want the well measured stars in this analysis.
    perrLim814 = 1.0 / scale
    perrLim125 = 4.0 / scale
    merrLim814 = 0.05
    merrLim125 = 0.1
    
    cond = ((t2005_814.m != 0) & (t2010_125.m != 0) &
            (t2010_139.m != 0) & (t2010_160.m != 0) &
            (t2005_814.xe < perrLim814) & (t2005_814.ye < perrLim814) &
            (t2010_125.xe < perrLim125) & (t2010_125.ye < perrLim125) &
            (t2010_139.xe < perrLim125) & (t2010_139.ye < perrLim125) &
            (t2010_160.xe < perrLim125) & (t2010_160.ye < perrLim125) &
            (t2005_814.me < merrLim814) & (t2010_125.me < merrLim125) &
            (t2010_139.me < merrLim125) & (t2010_160.me < merrLim125))

    t2005_814 = t2005_814.where(cond)
    t2010_125 = t2010_125.where(cond)
    t2010_139 = t2010_139.where(cond)
    t2010_160 = t2010_160.where(cond)

    # Calculate proper motions
    dt = years['2010_F125W'] - years['2005_F814W']
    dx = t2010_125.x - t2005_814.x
    dy = t2010_125.y - t2005_814.y
    pmx = dx * scale / dt
    pmy = dy * scale / dt
    pm = np.hypot(pmx, pmy)

    t2005_814.add_column('pmx', pmx)
    t2005_814.add_column('pmy', pmy)
    t2005_814.add_column('pm', pm)
    
    # Trim down to a 1 mas/yr radius
    pmCut = 1.0
    idx2 = np.where(pm < pmCut)[0]

    t2005_814 = t2005_814.where(idx2)
    t2010_125 = t2010_125.where(idx2)
    t2010_139 = t2010_139.where(idx2)
    t2010_160 = t2010_160.where(idx2)

    _o814 = open(workDir + '02.PMA/MASTER.F814W.ref5', 'w')
    _o125 = open(workDir + '02.PMA/MASTER.F125W.ref5', 'w')
    _o139 = open(workDir + '02.PMA/MASTER.F139M.ref5', 'w')
    _o160 = open(workDir + '02.PMA/MASTER.F160W.ref5', 'w')

    ofmt = '{0:10.4f} {1:10.4f} {2:8.4f} {3:10.4f} {4:10.4f} {5:8.4f} {6}\n'
    for ii in range(len(t2005_814)):
        _o814.write(ofmt.format(t2005_814.x[ii], t2005_814.y[ii], t2005_814.m[ii],
                                t2005_814.xe[ii], t2005_814.ye[ii], t2005_814.me[ii],
                                t2005_814.name[ii]))
        _o125.write(ofmt.format(t2010_125.x[ii], t2010_125.y[ii], t2010_125.m[ii],
                                t2010_125.xe[ii], t2010_125.ye[ii], t2010_125.me[ii],
                                t2010_125.name[ii]))
        _o139.write(ofmt.format(t2010_139.x[ii], t2010_139.y[ii], t2010_139.m[ii],
                                t2010_139.xe[ii], t2010_139.ye[ii], t2010_139.me[ii],
                                t2010_139.name[ii]))
        _o160.write(ofmt.format(t2010_160.x[ii], t2010_160.y[ii], t2010_160.m[ii],
                                t2010_160.xe[ii], t2010_160.ye[ii], t2010_160.me[ii],
                                t2010_160.name[ii]))

    _o814.close()
    _o125.close()
    _o139.close()
    _o160.close()
示例#11
0
def matchup_ks2_pass1(ks2Catalog, ks2FilterIdx, matchupFile, outSuffix=None):
    """
    Read in ks2 output and xym2mat files.
    Matchup to search for common sources.
    Return a table with all the measurements for comparison.
    """

    # Load the KS2 star list
    # Should be LOGR_catalo.fits produced by jlu.hst.starlists.process_ks2_output()
    #ks2 = atpy.Table(ks2Root + '.FIND_AVG_UV1_F.fits')
    ks2 = atpy.Table(ks2Catalog)
    suffix = '_%d' % ks2FilterIdx

    # Trim down the KS2 list to just stuff well-measured in the filter of interest.
    keepIdx = np.where((ks2['x' + suffix] != -1000) & (ks2['m' + suffix] != 0)
                       & (ks2['me' + suffix] < 1))[0]
    ks2 = ks2.rows(keepIdx)

    pass1 = starlists.read_matchup(matchupFile)
    keepIdx = np.where((pass1.x != -1000) & (pass1.m != 0) & (pass1.me < 1))[0]
    pass1 = pass1.rows(keepIdx)

    #####
    # For each star in the matchup list (with a valid measurement), search the ks2
    # data to find whether the star is measured. If it is, then compare the measurements
    # and unceratinties.
    #####
    ks2Indices = np.zeros(len(pass1), dtype=int)
    ks2Indices += -1  # -1 indicates no match

    print 'Starting search for {0} stars'.format(len(pass1))
    for ss in range(len(pass1)):
        if ss % 5000 == 0:
            print 'Reached star {0}'.format(ss)
        dr = np.hypot(pass1.x[ss] - ks2['x_0'], pass1.y[ss] - ks2['y_0'])
        rminIdx = dr.argmin()

        if dr[rminIdx] < 1:
            ks2Indices[ss] = rminIdx

    # Make a new table with x, y, m, xe, ye, me  First in ks2, then in pass1.
    in_p1 = np.where(ks2Indices >= 0)[0]
    in_ks2 = ks2Indices[in_p1]

    stars = atpy.Table()
    stars.add_column('x_ks2', ks2['x' + suffix][in_ks2])
    stars.add_column('y_ks2', ks2['y' + suffix][in_ks2])
    stars.add_column('m_ks2', ks2['m' + suffix][in_ks2])
    stars.add_column('xe_ks2', ks2['xe' + suffix][in_ks2])
    stars.add_column('ye_ks2', ks2['ye' + suffix][in_ks2])
    stars.add_column('me_ks2', ks2['me' + suffix][in_ks2])
    stars.add_column('x_pass1', pass1['x'][in_p1])
    stars.add_column('y_pass1', pass1['y'][in_p1])
    stars.add_column('m_pass1', pass1['m'][in_p1])
    stars.add_column('xe_pass1', pass1['xe'][in_p1])
    stars.add_column('ye_pass1', pass1['ye'][in_p1])
    stars.add_column('me_pass1', pass1['me'][in_p1])
    stars.table_name = ''

    if outSuffix == None:
        outSuffix = 'f{0}'.format(ksFilterIdx)

    stars.write('stars_ks2_pass1_{0}.fits'.format(outSuffix), overwrite=True)

    # Just for kicks, also produce a table of stars that WERE NOT in ks2.
    # This table will have the same format as the pass1 list.
    stars_pass1_only = pass1.where(ks2Indices == -1)
    stars_pass1_only.table_name = ''

    stars_pass1_only.write('stars_pass1_only_{0}.fits'.format(outSuffix),
                           overwrite=True)
示例#12
0
def matchup_ks2_pass1(ks2Catalog, ks2FilterIdx, matchupFile, outSuffix=None):
    """
    Read in ks2 output and xym2mat files.
    Matchup to search for common sources.
    Return a table with all the measurements for comparison.
    """

    # Load the KS2 star list
    # Should be LOGR_catalo.fits produced by jlu.hst.starlists.process_ks2_output()
    #ks2 = atpy.Table(ks2Root + '.FIND_AVG_UV1_F.fits')
    ks2 = atpy.Table(ks2Catalog)  
    suffix = '_%d' % ks2FilterIdx

    # Trim down the KS2 list to just stuff well-measured in the filter of interest.
    keepIdx = np.where((ks2['x'+suffix] != -1000) &
                       (ks2['m'+suffix] != 0) &
                       (ks2['me'+suffix] < 1))[0]
    ks2 = ks2.rows(keepIdx)

    pass1 = starlists.read_matchup(matchupFile)
    keepIdx = np.where((pass1.x != -1000) &
                       (pass1.m != 0) &
                       (pass1.me < 1))[0]
    pass1 = pass1.rows(keepIdx)

    #####
    # For each star in the matchup list (with a valid measurement), search the ks2
    # data to find whether the star is measured. If it is, then compare the measurements
    # and unceratinties.
    #####
    ks2Indices = np.zeros(len(pass1), dtype=int)
    ks2Indices += -1   # -1 indicates no match

    print 'Starting search for {0} stars'.format(len(pass1))
    for ss in range(len(pass1)):
        if ss % 5000 == 0:
            print 'Reached star {0}'.format(ss)
        dr = np.hypot( pass1.x[ss] - ks2['x_0'], pass1.y[ss] - ks2['y_0'] )
        rminIdx = dr.argmin()
            
        if dr[rminIdx] < 1:
            ks2Indices[ss] = rminIdx
                
    # Make a new table with x, y, m, xe, ye, me  First in ks2, then in pass1.
    in_p1 = np.where(ks2Indices >= 0)[0]
    in_ks2 = ks2Indices[in_p1]
            
    stars = atpy.Table()
    stars.add_column('x_ks2', ks2['x'+suffix][in_ks2])
    stars.add_column('y_ks2', ks2['y'+suffix][in_ks2])
    stars.add_column('m_ks2', ks2['m'+suffix][in_ks2])
    stars.add_column('xe_ks2', ks2['xe'+suffix][in_ks2])
    stars.add_column('ye_ks2', ks2['ye'+suffix][in_ks2])
    stars.add_column('me_ks2', ks2['me'+suffix][in_ks2])
    stars.add_column('x_pass1', pass1['x'][in_p1])
    stars.add_column('y_pass1', pass1['y'][in_p1])
    stars.add_column('m_pass1', pass1['m'][in_p1])
    stars.add_column('xe_pass1', pass1['xe'][in_p1])
    stars.add_column('ye_pass1', pass1['ye'][in_p1])
    stars.add_column('me_pass1', pass1['me'][in_p1])
    stars.table_name = ''

    if outSuffix == None:
        outSuffix = 'f{0}'.format(ksFilterIdx)

    stars.write('stars_ks2_pass1_{0}.fits'.format(outSuffix), overwrite=True)

    # Just for kicks, also produce a table of stars that WERE NOT in ks2.
    # This table will have the same format as the pass1 list.
    stars_pass1_only = pass1.where(ks2Indices == -1)
    stars_pass1_only.table_name = ''
    
    stars_pass1_only.write('stars_pass1_only_{0}.fits'.format(outSuffix), overwrite=True)