def test_four_param(): ''' tests the intial guess, which fits for rotation, scale , and translation terms ''' x = np.random.rand(1000) y = np.random.rand(1000) #now create translated coordiantes with known translation c_x = np.array([30,1,.1]) c_y = np.array([-40,-.1,1]) xp = c_x[0] + c_x[1]*x + c_x[2]*y yp = c_y[0] + c_y[1]*x + c_y[2]*y c_xn, c_yn = high_order.four_param(x,y,xp,yp) print c_x, c_xn print c_y, c_yn assert np.sum(np.abs(c_xn - c_x)) < .001 assert np.sum(np.abs(c_yn - c_y)) < .001
def test_a2(): ''' takes starset that is assumed to be linear transfomration align a2 uses a four parameter tranform, so for fair comparrison, we use the four parmeter tranform that is implemented as an intitial guess then we can compare both output coordiantes of aligna and of high_order ''' dat = Table.read('test/data.txt', format='ascii.fixed_width') trans = Table.read('test/a2.trans', format='ascii') x = dat['xorig'] y = dat['yorig'] xref = dat['xref'] yref = dat['yref'] xa2 = dat['xa2'] ya2 = dat['ya2'] c_x, c_y = high_order.four_param(x, y, xref, yref) xev = c_x[0] + c_x[1] * x + c_x[2] * y yev = c_y[0] + c_y[1] * x + c_y[2] * y #test that the coefficients agree to within 1% for the large linear term, and 2% for the smaller linear term (the linear y term for the s fit) assert (c_x[0] - trans['a0']) / c_x[0] < .0001 assert (c_x[1] - trans['a1']) / c_x[0] < .0001 assert (c_x[2] - trans['a2']) / c_x[0] < .0001 assert (c_y[0] - trans['b0']) / c_x[0] < .0001 assert (c_y[1] - trans['b2']) / c_x[0] < .0001 assert (c_y[2] - trans['b1']) / c_x[0] < .0001 #demand that the output coordinates agree to within .2 pixels assert np.mean(np.abs(xev - xa2)) < .2, np.mean(np.abs(xev - xa2)) assert np.mean(np.abs(yev - ya2)) < .2, np.mean(np.abs(yev - ya2))
def test_a2(): ''' takes starset that is assumed to be linear transfomration align a2 uses a four parameter tranform, so for fair comparrison, we use the four parmeter tranform that is implemented as an intitial guess then we can compare both output coordiantes of aligna and of high_order ''' dat = Table.read('test/data.txt', format='ascii.fixed_width') trans = Table.read('test/a2.trans', format='ascii') x = dat['xorig'] y = dat['yorig'] xref = dat['xref'] yref = dat['yref'] xa2 = dat['xa2'] ya2 = dat['ya2'] c_x, c_y = high_order.four_param(x,y,xref,yref) xev = c_x[0] + c_x[1] * x + c_x[2] * y yev = c_y[0] + c_y[1] * x + c_y[2] * y #test that the coefficients agree to within 1% for the large linear term, and 2% for the smaller linear term (the linear y term for the s fit) assert (c_x[0] - trans['a0']) /c_x[0] < .0001 assert (c_x[1] - trans['a1']) /c_x[0] < .0001 assert (c_x[2] - trans['a2']) /c_x[0] < .0001 assert (c_y[0] - trans['b0']) /c_x[0] < .0001 assert (c_y[1] - trans['b2']) /c_x[0] < .0001 assert (c_y[2] - trans['b1']) /c_x[0] < .0001 #demand that the output coordinates agree to within .2 pixels assert np.mean(np.abs(xev-xa2)) < .2, np.mean(np.abs(xev-xa2)) assert np.mean(np.abs(yev-ya2)) < .2, np.mean(np.abs(yev-ya2))
def test_four_param(): ''' tests the intial guess, which fits for rotation, scale , and translation terms ''' x = np.random.rand(1000) y = np.random.rand(1000) #now create translated coordiantes with known translation c_x = np.array([30, 1, .1]) c_y = np.array([-40, -.1, 1]) xp = c_x[0] + c_x[1] * x + c_x[2] * y yp = c_y[0] + c_y[1] * x + c_y[2] * y c_xn, c_yn = high_order.four_param(x, y, xp, yp) print c_x, c_xn print c_y, c_yn assert np.sum(np.abs(c_xn - c_x)) < .001 assert np.sum(np.abs(c_yn - c_y)) < .001
def match2hst_err(lis_f, ref, fits_file, ecut=.01, ref_scale=1.0, ap_dar=True, mat_new=True): ''' lis_f is the name of the fits table containing the Nirc2 coordiantes form a single pointing ref is the "distortion free" reference (either Nirc2 or HST) ecut (arcseconds) is the error cut that must be met for stars to be included in the 4 parameter tranfomtion between reference and lis_f ref_scale is scale if refernce catalog in arcsconds/pixel if not mat_new: Simply return the matches that were previosly known, this is only different by a few data points then rematching. ''' xinit = ref['Xarc'] yinit = ref['Yarc'] stf = Table.read(lis_f, format='fits') stf_pix_scale = .01 idhst = match_by_name(stf['col0'], ref['Name']) if not mat_new: hst_ebool = (ref['xerr'][idhst] < ecut / ref_scale) * ( ref['yerr'][idhst] < ecut / ref_scale) stf_ebool = (stf['col2'] < ecut / stf_pix_scale) * ( stf['col4'] < ecut / stf_pix_scale) tbool = hst_ebool * stf_ebool xhst, yhst = applyDAR_coo(fits_file, xinit * ref_scale, yinit * ref_scale) cx, cy = high_order.four_param(xhst[idhst][tbool], yhst[idhst][tbool], stf['col1'][tbool], stf['col3'][tbool]) xnew = cx[0] + cx[1] * xhst + cx[2] * yhst ynew = cy[0] + cy[1] * xhst + cy[2] * yhst return stf['col1'], stf['col3'], xnew[idhst], ynew[idhst], ref['Name'][ idhst], stf['col5'], ref['Mag'][idhst], ( ref['xerr'][idhst] * ref_scale) / stf_pix_scale, ( ref['yerr'][idhst] * ref_scale) / stf_pix_scale, stf['col2'], stf['col4'] if ap_dar: #this applies DAR to space coordinates, to make thme comparable to the Nirc2 distorted frames #import pdb;pdb.set_trace() xhst, yhst = applyDAR_coo(fits_file, xinit * ref_scale, yinit * ref_scale) else: xhst = xinit * ref_scale yhst = yinit * ref_scale #do error cut, then recalulcate 4 parameter tranforamtion of HST hst_ebool = (ref['xerr'][idhst] < ecut / ref_scale) * (ref['yerr'][idhst] < ecut / ref_scale) stf_ebool = (stf['col2'] < ecut / stf_pix_scale) * (stf['col4'] < ecut / stf_pix_scale) tbool = hst_ebool * stf_ebool cx, cy = high_order.four_param(xhst[idhst][tbool], yhst[idhst][tbool], stf['col1'][tbool], stf['col3'][tbool]) xnew = cx[0] + cx[1] * xhst + cx[2] * yhst ynew = cy[0] + cy[1] * xhst + cy[2] * yhst idx1, idx2, dm, dr = jay.match(stf['col1'], stf['col3'], stf['col5'], xnew, ynew, ref['Mag'], 3) print 'found ', len(idx1), ' matches out of ', len(stf['col4']) return stf['col1'][idx1], stf['col3'][idx1], xnew[idx2], ynew[idx2], ref[ 'Name'][idx2], stf['col5'][idx1], ref['Mag'][idx2], ( ref['xerr'][idx2] * ref_scale) / stf_pix_scale, ( ref['yerr'][idx2] * ref_scale ) / stf_pix_scale, stf['col2'][idx1], stf['col4'][idx1]
def precision_stack(lis_files, hst_tab_ref, hst_tab_red, order=3, plot_hist=False, pix_range=4, long_in_set=None, tab_format='fits', ap_dar=True): ''' Primary purpose of this code is to stack NIRC2 catalogs taken at the same position, and write the stacked catalogs. go through all the starfinder , match into hst Then keep only stars with a match for stacking in the Nirc2 frames THen find all frames that have >20 matches ( from triangle), and also have average dr < pix_range pixels and combine them ''' xstf = [] ystf = [] xref = [] yref = [] rms_x = [] rms_y = [] nstf = [] mstf = [] #hst_tab = Table.read(hst_file, format='ascii') long_in = 0 long_length = 0 lis_used = [] xstf = [] ystf = [] xref = [] yref = [] hxerr = [] hyerr = [] for i, lis_i in enumerate(lis_files): x, y, xr, yr, name, hst_bool, m_idx, mag, hst_mag, hst_xerr, hst_yerr = match2hst( lis_i, hst_tab_ref, hst_tab_red, ap_dar=ap_dar) if len(x) > 5: xstf.append(x) ystf.append(y) xref.append(hst_tab_red['Xarc'][hst_bool][m_idx]) yref.append(hst_tab_red['Yarc'][hst_bool][m_idx]) hxerr.append(hst_xerr) hyerr.append(hst_yerr) mstf.append(mag) nstf.append(name) lis_used.append(lis_i) if len(x) > long_length: long_in = i #we have a reference now, need to match into it if long_in_set != None: long_in = long_in_set #create matching dictionary lis_bool = np.ones(len(lis_used), dtype='bool') fnum = 0 fits_frames_index = [] mname = [] while np.sum(lis_bool) > 0: #import pdb;pdb.set_trace() m_dict = {} x_dict = {} y_dict = {} hste_dict = {} hst_pos_dict = {} #import pdb; pdb.set_trace() if lis_bool[fnum]: lis_bool[fnum] = False for i in range(len(xstf[fnum])): x_dict[nstf[fnum][i]] = [xstf[fnum][i]] y_dict[nstf[fnum][i]] = [ystf[fnum][i]] m_dict[nstf[fnum][i]] = [mstf[fnum][i]] hst_pos_dict[nstf[fnum][i]] = (xref[fnum][i], yref[fnum][i]) hste_dict[nstf[fnum][i]] = (hxerr[fnum][i], hyerr[fnum][i]) for ii in range(1, 20): #go through next 20 frames to make sure that we get the next frames we are looking for, should only be 4 frames for our observing frame #import pdb;pdb.set_trace() if ii + fnum < len(xstf): N, x1m, y1m, m1m, x2m, y2m, m2m = jay.miracle_match_briteN( xstf[fnum], ystf[fnum], mstf[fnum], xstf[ii + fnum], ystf[ii + fnum], mstf[ii + fnum], 60) if N > 9: print N, ' matches found' #tranform coordinates for final matching cx, cy = high_order.four_param(x2m, y2m, x1m, y1m) #import pdb;pdb.set_trace() if np.mean(x2m - x1m)**2 + np.mean( y2m - y1m)**2 < pix_range**2: lis_bool[ii + fnum] = False xnew = cx[0] + cx[1] * xstf[ ii + fnum] + cx[2] * ystf[ii + fnum] ynew = cy[0] + cy[1] * xstf[ ii + fnum] + cy[2] * ystf[ii + fnum] idx1, idx2, dm, dr = jay.match( xstf[fnum], ystf[fnum], mstf[fnum], xnew, ynew, mstf[ii + fnum], 2) #now I need to go through the names of the matched stars, and add coordinates for stars that are in the refernce list for kk in range(len(idx2)): if nstf[ii + fnum][idx2][kk] in x_dict.keys(): x_dict[nstf[ii + fnum][idx2][kk]].append( xnew[idx2][kk]) y_dict[nstf[ii + fnum][idx2][kk]].append( ynew[idx2][kk]) m_dict[nstf[ii + fnum][idx2][kk]].append( mstf[ii + fnum][idx2][kk]) #now calc precisions for all lists and write a series of files ! print 'base of catalog ', fnum print 'number of matched measurements for an arbitrary star ', len( x_dict[x_dict.keys()[0]]) xerr = [] yerr = [] x = [] y = [] mag = [] N = [] name_f = [] xref1 = [] yref1 = [] xrerr = [] yrerr = [] #fits_frames_index.append(fnum) for i in x_dict.keys(): if len(x_dict[i]) > 1: xerr.append(np.std(np.array(x_dict[i]))) x.append(np.mean(x_dict[i])) yerr.append(np.std(np.array(y_dict[i]))) y.append(np.mean(y_dict[i])) mag.append(np.mean(m_dict[i])) N.append(len(x_dict[i])) name_f.append(i) xref1.append(hst_pos_dict[i][0]) yref1.append(hst_pos_dict[i][1]) xrerr.append(hste_dict[i][0]) yrerr.append(hste_dict[i][0]) if x != []: #tab = Table(data=[name_f, x, xerr, y, yerr, mag, N], names = ['Name', 'x', 'xerr','y','yerr','mag','N']) tab = Table(data=[name_f, x, xerr, y, yerr, mag, N]) mname.append('match_' + str(fnum) + '.fits') fits_frames_index.append(fnum) tab.write('match_' + str(fnum) + '.fits', format='fits') tab.write('match_' + str(fnum) + '.txt', format='ascii.fixed_width') fnum += 1 out_fits = [] lis_used = np.array(lis_used) for s in lis_used[fits_frames_index]: out_fits.append('../../Data/april/' + str(s).replace('_0.8_stf.lis', '.fits.gz')) tab2 = Table(data=[out_fits, mname]) tab2.write('first_fits_m.lis', format='ascii.no_header') return xerr, yerr, mag, N
def match2hst(lis_f, hst_tab_ref, hst_tab_red): ''' lis_f is the name of the text file catalog of nirc2 positions matches the lis file from Starfinder with the HST reference uses the fact that the first star is in the HST Reference (by name) to trim down the Stars from HST for matching Note: the HST coordiantes for this are not DAR corrected I use a matching raius of 4 Nirc2 pixels (20 mas) ''' Looked_twice = False stf = Table.read(lis_f, format='ascii') refname = stf['col1'][0] hst = hst_tab_red ref_in = np.argmax(hst['Name'] == refname) xcen = hst_tab_ref['Xarc'][ref_in] ycen = hst_tab_ref['Yarc'][ref_in] hpix_scale = .05 #arcseconds/pixel #want a 20 arcsecond box, to make sure we get all stars that could match pix_r = 10 / hpix_scale hst_bool = (hst['Xarc'] < xcen + pix_r) * (hst['Xarc'] > xcen - pix_r) * ( hst['Yarc'] < ycen + pix_r) * (hst['Yarc'] > ycen - pix_r) #hst_bool = np.ones(hst['Xarc'].shape, dtype=bool) N, x1m, y1m, m1m, x2m, y2m, m2m = jay.miracle_match_briteN( stf['col4'], stf['col5'], stf['col2'], hst['Xarc'][hst_bool], hst['Yarc'][hst_bool], hst['Mag'][hst_bool], 60) if N < 5: looked_twice = True N, x1m, y1m, m1m, x2m, y2m, m2m = search_for_mat(hst, stf, num=60) if N == None: N, x1m, y1m, m1m, x2m, y2m, m2m = search_for_mat(hst, stf, fac=2, num=60) dm = np.average(m1m - m2m) #now use matched coordiantes to tranform the sftarfinder lists into hst frame. #then match again, only on coordiantes? keep it tight to avoid fake matches, also mind the potential for color terms between K and HST stfx = stf['col4'] stfy = stf['col5'] cx, cy = high_order.four_param(x2m, y2m, x1m, y1m) xnew = cx[0] + cx[1] * hst['Xarc'] + cx[2] * hst['Yarc'] ynew = cy[0] + cy[1] * hst['Xarc'] + cy[2] * hst['Yarc'] #now tranform hst into Nirc2 frame mbool = np.zeros(stf['col4'].shape, dtype='bool') hstin = [] #import pdb; pdb.set_trace() idx1, idx2, dm, dr = jay.match(stf['col4'], stf['col5'], stf['col2'], xnew, ynew, hst['Mag'], 4) #if we matched less than 20% of the stars, try matching again because something almost certainly went wrong print 'found ', len(idx1), ' matches out of ', len(stf['col4']) #assert len(idx1) > 5 #now we have more matches #what I need for the distortion solution is the delta to HST #and I also need the original pixel location on the chip #return those things, let everything go #consider savinf star name from hst list, to give chance to eliminate stars with bad measurements (Saturated, etc.) return stf['col4'][idx1], stf['col5'][idx1], xnew[idx2], ynew[idx2], hst[ 'Name'][idx2], np.ones(len(hst), dtype='bool'), idx2, stf['col2'][ idx1], hst['Mag'][idx2], hst['xerr'][idx2], hst['yerr'][idx2]
def match2hst_err_ret_hst(lis_f, fits_file, hst, tx, ty, ecut=.01, spline=False): ''' matches the lis_f is the stacked measurements from frames at a single pointing matches stars by name to the HST reference corrects for distortion based on tx,ty then corrects for DAR based on the information in the header of fits_file then tranforams the lis_f catalogs to the HST frame using a four parameter tranformation on stars with positional errors < ecut (arcseconds) returns coordinates in arcseconds in the HST frame called by mk_reference DOES NOT FIND NEW MATCHES ''' stf = Table.read(lis_f, format='fits') hpix_scale = .05 stf_pix_scale = .01 idhst = match_by_name(stf['col0'], hst['Name']) xorig = stf['col1'] yorig = stf['col3'] #first apply distortion solution, then apply DAR to get to space ref frame if not spline: dx, dy = tx.evaluate(xorig, yorig) xin = dx + xorig yin = dy + yorig else: xin = tx.ev(xorig, yorig) + xorig yin = ty.ev(xorig, yorig) + yorig (pa, darCoeffL, darCoeffQ) = nirc2dar(fits_file) sina = math.sin(pa) cosa = math.cos(pa) xnew2 = xin * cosa + yin * sina ynew2 = -xin * sina + yin * cosa # Apply DAR correction along the y axis xnew3 = xnew2 ynew3 = ynew2 * (1 + darCoeffL) + ynew2 * np.abs(ynew2) * darCoeffQ # Rotate coordinates counter-clockwise by PA back to original xstf = xnew3 * cosa - ynew3 * sina ystf = xnew3 * sina + ynew3 * cosa hst_ebool = (hst['xerr'][idhst] < ecut / hpix_scale) * (hst['yerr'][idhst] < ecut / hpix_scale) stf_ebool = (stf['col2'] < ecut / stf_pix_scale) * (stf['col4'] < ecut / stf_pix_scale) tbool = hst_ebool * stf_ebool #cx,cy = high_order.four_param(xin[tbool], yin[tbool],xhst[idhst][tbool], yhst[idhst][tbool]) cx, cy = high_order.four_param(xstf[tbool], ystf[tbool], hst['Xarc'][idhst][tbool], hst['Yarc'][idhst][tbool]) xnew = (cx[0] + cx[1] * xstf + cx[2] * ystf) * hpix_scale ynew = (cy[0] + cy[1] * xstf + cy[2] * ystf) * hpix_scale #idx1 , idx2 , dm, dr = jay.match(stf['col1'], stf['col3'] ,stf['col5'], xnew, ynew, hst['Mag'], 8) return xnew, ynew, stf['col0'], hst['Mag'][idhst], stf['col5']