def computeRotatorAngle(obs, SEP, PA, debug=False): if debug: print "RA, DEC:", obs[0]["RA"], obs[0]["DEC"] print np.arcsin(10.0 / SEP) * 180 / np.pi if SEP > 10 else 90 rot3 = [ ( prima.projBaseline(o["B_XYZA"], (o["RA"], o["DEC"]), o["LST"])["parang"] + PA + (np.arcsin(10.0 / SEP) * 180 / np.pi if SEP > 10 else 90) + 180 * o["SWAPPED"] + o["AZ3"] ) / 2.0 for o in obs ] rot3 = np.array(rot3) % 180 az3 = [prima.projBaseline(o["B_XYZA"], (o["RA"], o["DEC"]), o["LST"])["az"] for o in obs] pyplot.figure(0) pyplot.clf() pyplot.plot(np.array([o["ROT3"] for o in obs]) - rot3, ".r") pyplot.xlabel("index") pyplot.ylabel("ROT3 - computed (degrees)") pyplot.figure(1) pyplot.clf() pyplot.plot((np.array([o["AZ3"] for o in obs]) - az3) % 360, ".r") pyplot.xlabel("index") pyplot.ylabel("AZ - computed (degrees)") return
def opdFunc(obs, params): res = [] for o in obs: res.extend(prima.projBaseline([params['X'], params['Y'], params['Z'], params['A']], [o['RA'], o['DEC']], o['LST'], latitude = params['LAT'])['opd']), return np.array(res)
def leastsqOPDModel(p_fit, fit, p_fixed, obs): try: p = np.zeros(fit.size) p[np.where(fit)] = p_fit p[np.where(1-fit)] = p_fixed except: p = p_fit res = [] for x in obs: res.extend(prima.projBaseline(p,[x['RA'], x['DEC']], x['LST'])['opd']/x['AIRN']- x['DL2-DL1']) res = np.array(res) print 'B=', p, 'RMS (um)', res.std()*1e6 return np.array(res)
def simu3(): """ what if the baseline is different for SS and PS? -> for small error in baselines, the residuals are still very small but the separation and projection angle of the binary are wrong... """ ra = 12.0 # in h dec = -32.0 # in deg sep = 35.0 # in arcsec PA = 135.0 # in deg dra = sep*np.cos(PA*np.pi/180.)/(3600.*180.)*np.pi/15. # in h ddec = sep*np.sin(PA*np.pi/180.)/(3600.*180.)*np.pi # in deg print 'actual binary is SEP=', sep, '(\"), PA=', PA, '(deg)' base = np.array([-76.4,49.862,0]) # X,Y,Z in m G2-J2 print 'actual baseline is:', base, '(m)' dbase = np.array([0*100e-6,0,0.0]) # error in Baseline, in m lst = np.linspace(12, 16, 50) # in h zeroM = 1.0 # in m # projected baseline projUV = prima.projBaseline(base, [ra, dec], lst) projPA = np.arctan(projUV[0], projUV[1])*180/np.pi projB = np.sqrt( projUV[0]**2+ projUV[1]**2) # projected baseline with offset print 'error in baseline is:', dbase, '(m)' projUVp = prima.projBaseline(base+dbase, [ra, dec], lst) projPAp = np.arctan(projUVp[0], projUVp[1])*180/np.pi projBp = np.sqrt( projUVp[0]**2+ projUVp[1]**2) # astrometric observables dopd = zeroM + \ (prima.projBaseline(base, [ra, dec], lst)[2] -\ prima.projBaseline(base+dbase, [ra+dra, dec+ddec], lst)[2]) print 'dopd PTP=',dopd.ptp()*1e6, 'um' # swapped dopds = zeroM -\ (prima.projBaseline(base, [ra, dec], lst)[2] -\ prima.projBaseline(base+dbase, [ra+dra, dec+ddec], lst)[2]) # observable B = list(projBp) B.extend(list(projBp)) PA = list(projPAp) PA.extend(list(projPAp)) Sw = list(np.zeros(len(projBp))) Sw.extend(list(np.ones(len(projBp)))) dO = list(dopd) dO.extend(dopds) e = list(np.ones(2*len(dopd))*1e-6) parang = list(np.zeros(2*len(dopd))) obs = [np.array(B), np.array(PA), np.array(Sw), np.array(parang), np.array(dO), np.array(e)] # fit param = [35.0, 135.0, 1.0, 0,0,0] fit_param = [1 , 1 , 1 , 0,0,0] # prepare the fit w_fit = np.where(np.array(fit_param)) w_nfit = np.where(1-np.array(fit_param)) p_fit = np.array(param)[w_fit] if not len(p_fit)==len(param): p_fixed = np.array(param)[w_nfit] else: p_fixed = [] # -- fit plsq, cov, info, mesg, ier = \ scipy.optimize.leastsq(leastsqAstromSepSimple, p_fit, args=(fit_param,p_fixed,obs,), epsfcn=1e-5, ftol=0.005, full_output=True) #plsq = param print 'fitted binary is SEP=', plsq[0], '(\"), PA=', plsq[1], '(deg)' # compute model dopd_M = np.array([astromSepSimple([projBp[k], projPAp[k], 0], [plsq[0], plsq[1], plsq[2]]) for k in range(len(projBp))]) dopds_M = np.array([astromSepSimple([projBp[k], projPAp[k]+180, 1], [plsq[0], plsq[1], plsq[2]]) for k in range(len(projBp))]) residuals = (dopd-dopds - (dopd_M-dopds_M))*1e6 print 'peak to peak error in delta_dopdc is',\ residuals.max()-residuals.min(), '(microns)' pyplot.figure(0) pyplot.clf() pyplot.subplot(211) pyplot.plot(lst, dopd-dopds, '.k', label='data') pyplot.plot(lst, dopd_M-dopds_M, 'k-', label='model') pyplot.xlabel('LST (h)') pyplot.ylabel('direct - swapped (m)') pyplot.legend() pyplot.subplot(212) pyplot.plot(lst, (dopd-dopds - (dopd_M-dopds_M))*1e6, '.k') pyplot.xlabel('LST (h)') pyplot.ylabel(r'O-C ($\mu$m)') return
def interpListOfFiles(list_of_files, data_directory=None, first_guess=None, fit_param=None, shuffle=False, fit_only_files=None, env_file=None, T0=290.0, P0=734.0, plot=False, FSMplots=False, arbitrary_offsets=None, maxPolyOrder=None, maxResiduals=None, quiet=True, sigmaClipping=None, res2fits=False, saveCalibrated=False): """ - read many reduced files - re-interpolate baselines and PA using polynomial fit - fit separation - maxResiduals=4.0: plots residuals betwwen -4 and 4 microns - res2fits=True: save residuals to the fit - saveCalibrated=True: save calibrated dOPD, i.e. with removed zero metrology """ red = [] # tables of atom # load all reduced files for k, f in enumerate(list_of_files): # reduced file: rf = f.split('.')[0]+'_RED.fits' # load reduced file a = atom(os.path.join(data_directory,rf)) # print the table of loaded files: if not fit_only_files==None: if k in fit_only_files: fit='X' else: fit='_' else: fit = 'X' if not quiet: # pretty printing of data if k==0: N = len(rf) print '|idx |fit|INS.MODE | file'+' '*(len(rf)-3)+'| date '\ +' '*(len(a.date_obs)-4)+'|' print '| %2d | %1s | %7s | %s | %s |' % (k, fit, a.insmode, rf, a.date_obs) red.append(a) # table of reduced files # function fo convert MJD to LST: simple linear extrapolation mjd2lst = lambda x: (x-red[0].mjd[0])*(23.+56/60.+4/3600.) + red[0].lst[0] # re-interpolate all vars(mjd) with start and end, except OPL var_poly_c = {} for k in red[0].var_start_end.keys(): if not k[:3]=='OPL2': if k=='base' or k=='PA' or k=='airmass': nPoly = np.minimum(2*len(red)-2, 10) else: nPoly = len(red)//2+1 if not maxPolyOrder is None: nPoly = min(nPoly, maxPolyOrder) X = [a.mjd_PCR_start for a in red] X.extend([a.mjd_PCR_end for a in red]) Y = [a.var_start_end[k][0] for a in red] Y.extend([a.var_start_end[k][1] for a in red]) X = np.array(X) Y = np.array(Y) # points to fit if k=='seeing' or k=='tau0': w = np.where(Y>0) else: w = range(len(X)) # save polynomial coef var_poly_c[k] = np.polyfit(X[w]-X.mean(), Y[w], nPoly) # update each observation if k!= 'base' and k!='PA': for a in red: a.var_mjd[k] = np.polyval(var_poly_c[k] ,a.mjd-X.mean()) else: var_poly_c[k]= [0] if not env_file==None: # load Also environmental data. e = prima.env(env_file) dopl1 = [] dopl2 = [] for a in red: P = e.interpVarMJD('SitePressure')(a.mjd) # for AT3-G2-DL2(E) dist_G2 = a.A1L + a.var_mjd['OPL1']#.mean() T_G2 = (e.interpVarMJD('SiteTemp2m')(a.mjd)+ e.interpVarMJD('VLTItempSens6')(a.mjd)+ e.interpVarMJD('VLTI_HSS_TEMP2')(a.mjd)+ e.interpVarMJD('VLTI_HSS_TEMP4')(a.mjd)+ e.interpVarMJD('VLTI_HSS_TEMP2')(a.mjd)+ e.interpVarMJD('VLTItempSens5')(a.mjd))/6.+272 dopl_G2 = prima.n_air_P_T(1.0, P, T=T_G2)*dist_G2 dopl_G2_0 = prima.n_air_P_T(1.0, P0, T0)*dist_G2 # for AT4-J2-DL4(W) dist_J2 = a.A2L + a.var_mjd['OPL2']#.mean() T_J2 = (e.interpVarMJD('SiteTemp2m')(a.mjd)+ e.interpVarMJD('VLTItempSens16')(a.mjd)+ e.interpVarMJD('VLTI_HSS_TEMP2')(a.mjd)+ e.interpVarMJD('VLTI_HSS_TEMP1')(a.mjd)+ e.interpVarMJD('VLTI_HSS_TEMP2')(a.mjd)+ e.interpVarMJD('VLTItempSens5')(a.mjd))/6.+272 dopl_J2 = prima.n_air_P_T(1.0, P, T=T_J2)*dist_J2 dopl_J2_0 = prima.n_air_P_T(1.0, P0, T0)*dist_J2 dopl1.append(dopl_G2 - dopl_G2_0) dopl2.append(dopl_J2 - dopl_J2_0) # build observations tables for fitting base=[] PA =[] swap=[] d_al=[] d_al_err=[] parang = [] rot1 = [] rot2 = [] # correct for PRIMET glitches: OBSOLETE! #for a in red: # a.d_al -= correctForPrimetJumps_JSa(a.mjd, a.jump) # add offset if not arbitrary_offsets==None: for k in range(len(red)): red[k].d_al += arbitrary_offsets[k]*1e-6 # default: use all observations if fit_only_files==None: fit_only_files = range(len(red)) # all the variables, in separate lists... not very elegant for k in fit_only_files: base.extend(list(red[k].var_mjd['base'])) PA.extend(list(red[k].var_mjd['PA'])) swap.extend(list(red[k].swapped)) d_al.extend(list(red[k].d_al)) d_al_err.extend(list(red[k].d_al_err)) parang.extend(list(red[k].var_mjd['parang'])) rot1.extend(list(red[k].rot1)) rot2.extend(list(red[k].rot2)) base = np.array(base) PA = np.array(PA) swap = np.array(swap) d_al = np.array(d_al) d_al_err = np.array(d_al_err) parang = np.array(parang) rot1 = np.array(rot1) rot2 = np.array(rot2) d_al_err = np.maximum(d_al_err, 1e-7) if shuffle: if isinstance(shuffle, int) and shuffle>1: np.random.seed(shuffle) wfit = np.random.randint(len(base), size=len(base)) else: wfit = range(len(base)) rot1 = 0 # force using parallactic if np.any(rot1): # we use rotators positions: #print 'USING rotator recordings' obs = [base[wfit], PA[wfit], swap[wfit], rot1[wfit], rot2[wfit], d_al[wfit], d_al_err[wfit]] if first_guess == None: param = [35, 40.0, .015,0,0,0,0] fit_param= [1, 1, 1 ,1,1,1,1] else: param = first_guess else: # we use parallactic angle: #print 'USING parallactic angle' obs = [base[wfit], PA[wfit], swap[wfit], parang[wfit], d_al[wfit], d_al_err[wfit]] if first_guess == None: param = [35, 40.0, .015,0,0] fit_param= [1, 1, 1 ,1,1] else: param = first_guess #print 'PARAMS:', param #print 'FIT_PARAM:',fit_param # --------- least square fit of the separation vector --------------- # prepare the fit w_fit = np.where(np.array(fit_param)) w_nfit = np.where(1-np.array(fit_param)) p_fit = np.array(param)[w_fit] if not len(p_fit)==len(param): p_fixed = np.array(param)[w_nfit] else: p_fixed = [] # fit if np.sum(fit_param)>0: plsq, cov, info, mesg, ier = \ scipy.optimize.leastsq(leastsqAstromSepSimple, p_fit, args=(fit_param,p_fixed,obs,), epsfcn=1e-5, ftol=0.005, full_output=True) else: plsq = [] # rebuild the complete parameter vector best = 1.0*np.array(param) best[w_fit] = plsq if best[0]<0: best[0] = abs(best[0]) best[1] += 180 chi2 = leastsqAstromSepSimple(best,None,None,obs)**2 chi2_red = np.sum(chi2)/len(chi2) s = chi2.argsort() chi2_99pc = np.sum(chi2[s[:int(0.99*len(s))]])/(0.99*len(chi2)) chi2_95pc = np.sum(chi2[s[:int(0.95*len(s))]])/(0.95*len(chi2)) chi2_90pc = np.sum(chi2[s[:int(0.90*len(s))]])/(0.90*len(chi2)) # build error vector err = np.zeros(len(param)) if np.sum(p_fit)>0: err[w_fit] = np.sqrt(np.abs(np.diag(cov)*np.sum(chi2))) vars_ = ['sep', 'PA ', 'M0 ', 'cos', 'phi', 'cos', 'phi'] units_ = ['\"', 'deg', 'mm ', 'um/\"', 'rad', 'um/\"', 'rad'] if not quiet: print '+------------+-----------------------+' for k in range(len(err)): print '| %3s (%4s) | %10.5f +- %7.5f |' %\ (vars_[k], units_[k], best[k], err[k]) print '+------------+-----------------------+' print 'PA baseline:', min([x.var_start_end['PA'][0] for x in red]), '->',\ max([x.var_start_end['PA'][1] for x in red]) print 'proj baseline:', min([x.var_start_end['base'][0] for x in red]), '->',\ max([x.var_start_end['base'][1] for x in red]) print 'CHI2_RED =', round(chi2_red,2) print 'CHI2_[99, 95, 90]%%= [%5.2f, %5.2f, %5.2f]' % \ (round(chi2_99pc,2), round(chi2_95pc,2) , round(chi2_90pc,2)) print 'correlation between PA and sep=', cov[0,1]/np.sqrt(cov[0,0]*cov[1,1]) else: return {'param':best, 'err':err, 'vars':vars_[:len(err)], 'chi2':chi2_red, 'units':units_[:len(err)], 'B_length':(min([x.var_start_end['base'][0] for x in red]), max([x.var_start_end['base'][0] for x in red])), 'B_PA':(min([x.var_start_end['PA'][0] for x in red]), max([x.var_start_end['PA'][0] for x in red])), 'target':red[0].PS_ID+'-'+red[0].SS_ID, 'MJD-OBS':(min([a.mjd_PCR_start for a in red]), max([a.mjd_PCR_end for a in red]))} if res2fits: ### export the residuals to the fit as FITS file ### compute the residuals: mjd_min = [] mjd_max = [] all_res = [] all_mjd = [] all_lst = [] all_proj = [] all_pa = [] all_parang=[] fitted_res = [] flip_sign = 1.0 # put to -1 to flip sign, 1 otherwise for k, a in enumerate(red): # for each files (stored in red): mjd_min.append(a.mjd.min()) mjd_max.append(a.mjd.max()) all_lst.extend(list(a.lst)) all_mjd.extend(list(a.mjd)) UV = prima.projBaseline(red[0].baseXYZ, red[0].radec, a.lst) baseB = UV['B'] all_proj.extend(list(baseB)) basePA = UV['PA'] all_pa.extend(list(basePA)) parang=UV['parang'] all_parang.extend(list(parang)) all_res.extend(1e6*(flip_sign)**a.swapped* (a.d_al- astromSepSimple([baseB, basePA, a.swapped, parang], best))) # create fits files hdu = pyfits.PrimaryHDU(None) # list of keywords to propagate from first element of red list_of_kw = ['OBJECT', 'RA', 'DEC', 'EQUINOX'] for k in list_of_kw: hdu.header.update(k, red[0].data[0].header[k]) hdu.header.update('MJDSTART', min(mjd_min)) hdu.header.update('MJDEND', min(mjd_max)) print best hdu.header.update('FIT_SEP', best[0], 'binary separation in arcsec') hdu.header.update('FIT_PA', best[1], 'binary angle in deg') hdu.header.update('FIT_ZERO', best[2], 'metrology zero point, in mm') for k, a in enumerate(red): hdu.header.update('ORIF'+str(k), red[k].data[0].header['ORIGFILE']) hdu.header.update('ARCF'+str(k), red[k].data[0].header['ARCFILE']) cols = [] cols.append(pyfits.Column(name='MJD', format='F12.5', array=all_mjd)) cols.append(pyfits.Column(name='LST', format='F11.8', array=all_lst, unit='h')) cols.append(pyfits.Column(name='PROJ_BASE', format='F8.4', array=all_proj, unit='m')) cols.append(pyfits.Column(name='PA_BASE', format='F8.4', array=all_pa, unit='deg')) cols.append(pyfits.Column(name='residuals', format='F8.3', array=all_res, unit='um')) hducols = pyfits.ColDefs(cols) hdub = pyfits.new_table(hducols) hdub.header.update('EXTNAME', 'ASTROM_FIT_RESIDUALS', '') thdulist = pyfits.HDUList([hdu, hdub]) print '--- saving residuals.fits ---' thdulist.writeto('residuals.fits') # done! if saveCalibrated: for a in red: #Create new file cols = [a.data['ASTROMETRY_BINNED'].columns[k] for k in len(a.data['ASTROMETRY_BINNED'].columns)] cols.append(pyfits.Column(name='D_AL_ZEROED', format='F12.9', array=a.data['ASTROMETRY_BINNED'].data.field['D_AL']- best[2]*1e-3)) if plot: ### x in MJD x = np.linspace(min([a.mjd_PCR_start for a in red])-0.003, max([a.mjd_PCR_end for a in red])+0.003, 300) f = pyplot.figure(0, figsize=(10,7)) pyplot.clf() f.subplots_adjust(hspace=0.05, top=0.95, left=0.13, right=0.98, bottom=0.1) ### metrology measurements #################### ax1 = pyplot.subplot(211) pyplot.title(red[0].PS_ID+'-'+red[0].SS_ID+' (MJD '+ str(round(min([a.mjd_PCR_start for a in red]), 3))+ ' -> '+ str(round(max([a.mjd_PCR_end for a in red]), 3))+')') pyplot.setp(ax1.get_xticklabels(), visible=False) pyplot.ylabel('PRIMET swapping (mm)') # zero point: pyplot.hlines(best[2], np.array([a.mjd_PCR_start for a in red]).min()-0.003, np.array([a.mjd_PCR_end for a in red]).max()+0.003, color='g', linestyle='dotted', linewidth=2) # model UV = prima.projBaseline(red[0].baseXYZ, red[0].radec, mjd2lst(x)) baseB = UV['B'] basePA = UV['PA'] parang = UV['parang'] pyplot.plot(x, 1e3*astromSepSimple([baseB, basePA, np.zeros(len(x)), parang], best), linestyle='-', linewidth=2, color='y') pyplot.plot(x, 1e3*astromSepSimple([baseB, basePA, np.ones(len(x)), parang], best), linestyle='--', linewidth=2, color='c') # measurements for k, a in enumerate(red): if (k==np.array(fit_only_files)).max(): style = 'pg' # fitted else: style = '+r' # not fitted #pyplot.errorbar(a.mjd, a.d_al, yerr=a.d_al_err, # color='k', marker=None) pyplot.plot(a.mjd, 1e3*a.d_al, style, alpha=0.1) ### residuals*(-1)**swapped to model ################### flip_sign = -1.0 # put to -1 to flip sign, 1 otherwise #flip_sign = 1 pyplot.subplot(212, sharex=ax1) yl = r'residuals ' if flip_sign == -1: yl = yl+' flipped ' yl = yl+'($\mu$m)' pyplot.ylabel(yl) # 0-line pyplot.hlines([0], np.array([a.mjd_PCR_start for a in red]).min()-0.003, np.array([a.mjd_PCR_end for a in red]).max()+0.003, color='0.5', linewidth=2, linestyle='-') ########## compute residuals: ##################### # data points mjd_avg = [] res_avg = [] b_lab_f = True b_lab_u = True # for each reduced file: all_res = [] fitted_res = [] for k, a in enumerate(red): # for each reduced obsering block mjd_avg.append(a.mjd.mean()) if np.any(rot1): bam = [a.var_mjd['base'], a.var_mjd['PA'], a.swapped, a.rot1, a.rot2] else: bam = [a.var_mjd['base'], a.var_mjd['PA'], a.swapped, a.var_mjd['parang']] all_res.extend(1e6*(flip_sign)**a.swapped* (a.d_al-astromSepSimple(bam,best))) res_avg.append(np.median(1e6*(flip_sign)**a.swapped* (a.d_al-astromSepSimple(bam,best)))) if (k==np.array(fit_only_files)).max(): style = 'pg' # fitted if b_lab_f: label='fitted' b_lab_f=False else: label=None fitted_res.extend(1e6*(flip_sign)**a.swapped* (a.d_al-astromSepSimple(bam,best))) else: style = '+r' # not fitted if b_lab_u: label='not fitted' b_lab_u=False else: label=None # plot residuals for this observing block pyplot.plot(a.mjd, 1e6*(flip_sign)**a.swapped* (a.d_al-astromSepSimple(bam, best)), style, label=label, alpha=0.5) sor = np.array(fitted_res)[np.array(fitted_res).argsort()] pseudo_std = (sor[int(0.84*len(sor))]-sor[int(0.15*len(sor))])/2 print 'residuals RMS=', np.array(fitted_res).std(), 'microns' print 'residuals pseudo RMS=', pseudo_std , 'microns' mjd_avg = np.array(mjd_avg) res_avg = np.array(res_avg) # 1-position per cluster w = np.where(np.array([a.swapped.mean()==0 for a in red])) s = mjd_avg[w].argsort() w = w[0][s] pyplot.plot(mjd_avg[w], res_avg[w], 'sy', linewidth=3, linestyle='-', label='NORMAL', markersize=8, alpha=0.8) w = np.where(np.array([a.swapped.mean()==1 for a in red])) s = mjd_avg[w].argsort() w = w[0][s] pyplot.plot(mjd_avg[w], res_avg[w], 'dc', linewidth=3, alpha=0.8, linestyle='dashed', label='SWAPPED', markersize=10) if not arbitrary_offsets==None: for k in range(len(red)): if k==0: label='offsets' else: label=None pyplot.hlines([(-1)**(red[k].swapped.mean())*arbitrary_offsets[k]], red[k].mjd.min(), red[k].mjd.max(), color=(0.8, 0.3, 0), linewidth=3, label=label) # -- plot metrology jumps #pyplot.plot(x, correctForPrimetJumps(x, red[0].jump*1e6), # color='m', linestyle='-.', linewidth=2, label='jumps') pyplot.legend(loc='upper left', ncol=4, bbox_to_anchor=(.0, 1.02, 1.2, .05)) if not maxResiduals is None: pyplot.ylim(-maxResiduals, maxResiduals) pyplot.xlabel('MJD') #---------- FSM plots ------------ if FSMplots: pyplot.figure(2, figsize=(10,8)) pyplot.clf() pyplot.subplots_adjust(top=0.95, left=0.05, right=0.98, bottom=0.05) for sts in [1,2]: for fsm in [1,2]: pyplot.subplot(220+(sts-1)*2+fsm) pyplot.title('STS'+str(sts)+' FSM'+str(fsm)+':pos in $\mu$m') if sts==1 and fsm==1: # AT3 FSM1 fsm_lims = [22,25,20,28] fsm_p = [10.5, -0.285, 10.5, 0.446] elif sts==2 and fsm==1: # AT4 FSM1 fsm_lims = [25,28,20,28] #fsm_p = [20, -0.491, 20, 0.315] fsm_p = [20, -0.025, 20, -0.210] elif sts==1 and fsm==2: # AT3 FSM2 fsm_lims = [6,9,7,15] fsm_p = [6.5, -0.046, 10.5, -0.063] elif sts==2 and fsm==2: # AT4 FSM2 fsm_lims = [8.5,11.5,7,15] #fsm_p = [10, -0.025, 10, -0.210] fsm_p = [10, -0.491, 10, 0.315] xp, yp = np.meshgrid(np.linspace(fsm_lims[0],fsm_lims[1],100), np.linspace(fsm_lims[2],fsm_lims[3],100)) dopd = (xp-fsm_p[0])*fsm_p[1] + (yp-fsm_p[2])*fsm_p[3] print 'dopd:', dopd.min(), dopd.max() pyplot.pcolormesh(xp,yp, dopd, vmin=-2, vmax=5) pyplot.colorbar() for x in red: pyplot.plot([x.data[0].header['ESO ISS PRI STS'+str(sts)+ ' FSMPOSX'+str(fsm)+' START'], x.data[0].header['ESO ISS PRI STS'+str(sts)+ ' FSMPOSX'+str(fsm)+' END']], [x.data[0].header['ESO ISS PRI STS'+str(sts)+\ ' FSMPOSY'+str(fsm)+' START'], x.data[0].header['ESO ISS PRI STS'+str(sts)+\ ' FSMPOSY'+str(fsm)+' END']], ('sy-' if x.insmode=='NORMAL' else 'dc-'), markersize=14) return # skip additional plots pyplot.figure(2, figsize=(4,4)) pyplot.clf() pyplot.subplot(111, polar=True) sortmjd = np.array([x.mjd_PCR_start for x in red]).argsort() PAmin = [x.var_start_end['PA'][0] for x in red][sortmjd[0]] PAmax = [x.var_start_end['PA'][1] for x in red][sortmjd[-1]] pyplot.bar(PAmin*np.pi/180., 1, width =(PAmax-PAmin)*np.pi/180., color='red', alpha=0.5, label='baseline') pyplot.bar(PAmin*np.pi/180.+np.pi, 1, width =(PAmax-PAmin)*np.pi/180., color='red', alpha=0.5) pyplot.plot([best[1]*np.pi/180,best[1]*np.pi/180], [0,1], color='k', alpha=0.8, linewidth=5, label='binary') pyplot.legend() #return #-------------------------------------------------- f = pyplot.figure(1, figsize=(14,10)) pyplot.clf() f.subplots_adjust(hspace=0.04, top=0.97, left=0.1, right=0.98, bottom=0.05) #### polynomial interpolations ################## n = len(var_poly_c.keys()) ### x in MJD x = np.linspace(min([a.mjd_PCR_start for a in red])-0.003, max([a.mjd_PCR_end for a in red])+0.003, 300) for i,k in enumerate(var_poly_c.keys()): if i==0: ax0 = pyplot.subplot(n,2,1+2*i) pyplot.title('interpolation') pyplot.setp(ax0.get_xticklabels(), visible=False) else: ax1 = pyplot.subplot(n,2,1+2*i, sharex=ax0) if not i==(n-1): pyplot.setp(ax1.get_xticklabels(), visible=False) else: pyplot.xlabel('MJD') pyplot.ylabel(k) if len(var_poly_c[k])>1: pyplot.plot(x, np.polyval(var_poly_c[k], x-X.mean()), 'k-') for a in red: if k=='base' or k=='PA': pyplot.plot(a.mjd, a.var_mjd[k], '.r') else: pyplot.plot(a.mjd, a.var_mjd[k], '.y') pyplot.plot(a.mjd_PCR_start, a.var_start_end[k][0], 'oy') pyplot.plot(a.mjd_PCR_end, a.var_start_end[k][1], 'oy') # residuals ax2 = pyplot.subplot(n,2,2+2*i, sharex=ax0) if not i==(n-1): pyplot.setp(ax2.get_xticklabels(), visible=False) else: pyplot.xlabel('MJD') if i==0: pyplot.title('residual') pyplot.hlines([0], np.array([a.mjd_PCR_start for a in red]).min()-0.003, np.array([a.mjd_PCR_end for a in red]).max()+0.003, color='k') if len(var_poly_c[k])>1: for a in red: pyplot.plot([a.mjd_PCR_start,a.mjd_PCR_end], [a.var_start_end[k][0]- np.polyval(var_poly_c[k], a.mjd_PCR_start-X.mean()), a.var_start_end[k][1]- np.polyval(var_poly_c[k], a.mjd_PCR_end-X.mean())], 'oy-') return
def __init__(self, filename, debug=False): he = 'HIERARCH ESO ' self.data = pyfits.open(filename) self.date_obs = self.data[0].header['DATE-OBS'] self.targname = self.data[0].header['HIERARCH ESO OBS TARG NAME'] self.PS_ID = self.data[0].header['HIERARCH ESO OCS PS ID'] self.SS_ID = self.data[0].header['HIERARCH ESO OCS SS ID'] self.mjd_obs = self.data[0].header['MJD-OBS'] self.lst_obs = self.data[0].header['LST']/3600. self.mjd= self.data['ASTROMETRY_BINNED'].data.field('MJD') # simple linear interpolation self.lst = self.lst_obs + (self.mjd - self.mjd_obs)*(23.+56/60.+4/3600.) self.d_al= self.data['ASTROMETRY_BINNED'].data.field('D_AL') self.d_al_err= self.data['ASTROMETRY_BINNED'].data.field('D_AL_err') try: self.rot1= self.data['ASTROMETRY_BINNED'].data.field('ROT1') self.rot2= self.data['ASTROMETRY_BINNED'].data.field('ROT2') except: self.rot1= np.zeros(len(self.d_al)) self.rot2= np.zeros(len(self.d_al)) self.mjd_PCR_start = astro.tag2mjd(self.data[0].header[he+'PCR ACQ START']) self.mjd_PCR_end = astro.tag2mjd(self.data[0].header[he+'PCR ACQ END']) self.lst_PCR_start = astro.tag2lst(self.data[0].header['ESO PCR ACQ START'], longitude=self.data[0].header['ESO ISS GEOLON']) self.A1L = self.data[0].header[he+'ISS CONF A1L'] self.A2L = self.data[0].header[he+'ISS CONF A2L'] try: self.insmode = self.data[0].header[he+'ISS PRI STS3 GUIDE_MODE'] except: self.insmode = self.data[0].header[he+'INS MODE'] cP = self.data[0].header[he+'ISS PRI MET C'] # in m/s dnuP = self.data[0].header[he+'ISS PRI MET F_SHIFT']*1e6 # in Hz nuP = self.data[0].header[he+'ISS PRI MET LASER_F'] #self.jump = (cP * dnuP/2/(nuP**2) ) * ( 2**24-1 ) # PRIMET jump in m, COMM14 self.jump = (cP * dnuP/2/(nuP**2) ) * ( 2**31-1 ) # PRIMET jump in m, COMM15 if 'SWAP' in self.insmode: # legacy: was SWAP at some point, now is SWAPPED self.swapped = np.ones(len(self.mjd)) else: astro.tag2lst(self.data[0].header['ESO PCR ACQ START'], longitude=self.data[0].header['ESO ISS GEOLON']) self.swapped = np.zeros(len(self.mjd)) # dictionnary of variables(mjd) START names = ['base', 'PA', 'OPL1', 'OPL2', 'airmass', 'tau0','seeing', 'parang'] keyw = ['ISS PBL12', 'ISS PBLA12', 'DEL DLT1 OPL', 'DEL DLT2 OPL', 'ISS AIRM', 'ISS AMBI TAU0', 'ISS AMBI FWHM', 'ISS PARANG'] self.var_start_end = {} for k in range(len(names)): self.var_start_end[names[k]] =(self.data[0].header[he+keyw[k]+' START'], self.data[0].header[he+keyw[k]+' END']) self.var_mjd={} # linear interpolation for k in self.var_start_end.keys(): if k != 'base' and k != 'PA': self.var_mjd[k] = self.var_start_end[k][0]+\ (self.mjd - self.mjd_PCR_start)/\ (self.mjd_PCR_end - self.mjd_PCR_start)*\ (self.var_start_end[k][1]- self.var_start_end[k][0]) else: # compute baselines self.baseXYZ = [self.data[0].header[he+'ISS CONF T1X']- self.data[0].header[he+'ISS CONF T2X'], self.data[0].header[he+'ISS CONF T1Y']- self.data[0].header[he+'ISS CONF T2Y'], self.data[0].header[he+'ISS CONF T1Z']- self.data[0].header[he+'ISS CONF T2Z'], self.data[0].header[he+'ISS CONF A1L']- self.data[0].header[he+'ISS CONF A2L']] # coordinates, corrected for proper motion self.radec = [astro.ESOcoord2decimal(self.data[0].header['ESO OCS TARG1 ALPHAPMC']), astro.ESOcoord2decimal(self.data[0].header['ESO OCS TARG2 DELTAPMC'])] self.radec = [self.data[0].header['RA']/15., self.data[0].header['DEC']] bb = prima.projBaseline(self.baseXYZ, self.radec, self.lst) if k == 'base': self.var_mjd[k] = bb['B'] if debug: print 'DEBUG: PBL12 START: computed', self.var_mjd[k][0],\ 'in header:', self.data[0].header[he+'ISS PBL12 START'], \ 'DELTA=', self.var_mjd[k][0]-self.data[0].header[he+'ISS PBL12 START'] print 'DEBUG: PBL12 END : computed', self.var_mjd[k][-1],\ 'in header:', self.data[0].header[he+'ISS PBL12 END'], \ 'DELTA=', self.var_mjd[k][-1]-self.data[0].header[he+'ISS PBL12 END'] if k == 'PA': self.var_mjd[k] = bb['PA'] if debug: print 'DEBUG: PBLA12 START: computed', self.var_mjd[k][0],\ 'in header:', self.data[0].header[he+'ISS PBLA12 START'],\ 'DELTA=', self.var_mjd[k][0]-self.data[0].header[he+'ISS PBLA12 START'] print 'DEBUG: PBLA12 END : computed', self.var_mjd[k][-1],\ 'in header:', self.data[0].header[he+'ISS PBLA12 END'],\ 'DELTA=', self.var_mjd[k][-1]-self.data[0].header[he+'ISS PBLA12 END'] self.data.close() return
def __init__(self, filename, debug=False): he = "HIERARCH ESO " self.data = pyfits.open(filename) self.filename = filename self.date_obs = self.data[0].header["DATE-OBS"] self.targname = self.data[0].header["HIERARCH ESO OBS TARG NAME"] self.PS_ID = self.data[0].header["HIERARCH ESO OCS PS ID"] self.SS_ID = self.data[0].header["HIERARCH ESO OCS SS ID"] self.mjd_obs = self.data[0].header["MJD-OBS"] self.lst_obs = self.data[0].header["LST"] / 3600.0 self.mjd = self.data["ASTROMETRY_BINNED"].data.field("MJD") try: self.lst = self.data["ASTROMETRY_BINNED"].data.field("LST") except: print "WARNING: USING BAD LST!" self.lst = self.lst_obs + (self.mjd - self.mjd_obs) * (23.0 + 56 / 60.0 + 4 / 3600.0) self.d_al = self.data["ASTROMETRY_BINNED"].data.field("D_AL") if self.PS_ID == "HD129926" and self.mjd_obs < 56005.0: # problem with these observations print "WARNING: KLUDGING D_AL -> -DA_L!!!" self.d_al *= -1 self.d_al_err = self.data["ASTROMETRY_BINNED"].data.field("D_AL_err") try: self.rot3 = self.data["ASTROMETRY_BINNED"].data.field("ROT3") self.rot4 = self.data["ASTROMETRY_BINNED"].data.field("ROT4") self.az3 = self.data["ASTROMETRY_BINNED"].data.field("AZ3") self.az4 = self.data["ASTROMETRY_BINNED"].data.field("AZ4") self.alt3 = self.data["ASTROMETRY_BINNED"].data.field("ALT3") self.alt4 = self.data["ASTROMETRY_BINNED"].data.field("ALT4") except: self.rot3 = np.zeros(len(self.d_al)) self.rot4 = np.zeros(len(self.d_al)) self.az3 = np.zeros(len(self.d_al)) self.az4 = np.zeros(len(self.d_al)) self.alt3 = np.zeros(len(self.d_al)) self.alt4 = np.zeros(len(self.d_al)) self.mjd_PCR_start = astro.tag2mjd(self.data[0].header[he + "PCR ACQ START"]) self.mjd_PCR_end = astro.tag2mjd(self.data[0].header[he + "PCR ACQ END"]) self.lst_PCR_start = astro.tag2lst( self.data[0].header["ESO PCR ACQ START"], longitude=self.data[0].header["ESO ISS GEOLON"] ) self.A1L = self.data[0].header[he + "ISS CONF A1L"] self.A2L = self.data[0].header[he + "ISS CONF A2L"] try: self.insmode = self.data[0].header[he + "ISS PRI STS3 GUIDE_MODE"] except: self.insmode = self.data[0].header[he + "INS MODE"] if not self.insmode in ["NORMAL", "SWAPPED"]: # print 'WARNING: unknown INSMODE=', self.insmode pass if self.insmode == "INCONSISTENT": # -- try to guess if self.data[0].header[he + "DEL FT SENSOR"] == "FSUB": self.insmode = "NORMAL" elif self.data[0].header[he + "DEL FT SENSOR"] == "FSUA": self.insmode = "SWAPPED" # print ' -> guessing: INSMODE=', self.insmode cP = self.data[0].header[he + "ISS PRI MET C"] # in m/s dnuP = self.data[0].header[he + "ISS PRI MET F_SHIFT"] * 1e6 # in Hz nuP = self.data[0].header[he + "ISS PRI MET LASER_F"] # self.jump = (cP*dnuP/2/(nuP**2))*(2**24-1) # PRIMET jump in m, COMM14 self.jump = (cP * dnuP / 2 / (nuP ** 2)) * (2 ** 31 - 1) # PRIMET jump in m, COMM15 if "SWAP" in self.insmode: # legacy: was SWAP at some point self.swapped = np.ones(len(self.mjd)) else: astro.tag2lst(self.data[0].header["ESO PCR ACQ START"], longitude=self.data[0].header["ESO ISS GEOLON"]) self.swapped = np.zeros(len(self.mjd)) # dictionnary of variables(mjd) START names = ["base", "PA", "OPL1", "OPL2", "airmass", "tau0", "seeing", "parang"] keyw = [ "ISS PBL12", "ISS PBLA12", "DEL DLT1 OPL", "DEL DLT2 OPL", "ISS AIRM", "ISS AMBI TAU0", "ISS AMBI FWHM", "ISS PARANG", ] self.var_start_end = {} for k in range(len(names)): self.var_start_end[names[k]] = ( self.data[0].header[he + keyw[k] + " START"], self.data[0].header[he + keyw[k] + " END"], ) self.var_mjd = {} # linear interpolation for k in self.var_start_end.keys(): if k != "base" and k != "PA": self.var_mjd[k] = self.var_start_end[k][0] + (self.mjd - self.mjd_PCR_start) / ( self.mjd_PCR_end - self.mjd_PCR_start ) * (self.var_start_end[k][1] - self.var_start_end[k][0]) else: # compute baselines self.baseXYZ = [ self.data[0].header[he + "ISS CONF T1X"] - self.data[0].header[he + "ISS CONF T2X"], self.data[0].header[he + "ISS CONF T1Y"] - self.data[0].header[he + "ISS CONF T2Y"], self.data[0].header[he + "ISS CONF T1Z"] - self.data[0].header[he + "ISS CONF T2Z"], self.data[0].header[he + "ISS CONF A1L"] - self.data[0].header[he + "ISS CONF A2L"], ] # coordinates, corrected for proper motion try: self.radec = [ astro.ESOcoord2decimal(self.data[0].header["ESO OCS TARG1 ALPHAPMC"]), astro.ESOcoord2decimal(self.data[0].header["ESO OCS TARG1 DELTAPMC"]), ] except: print "WARNING: could not find precessed coordinates in header!" self.radec = [ astro.ESOcoord2decimal(self.data[0].header["ESO ISS REF RA"]), astro.ESOcoord2decimal(self.data[0].header["ESO ISS REF DEC"]), ] self.radec = [self.data[0].header["RA"] / 15.0, self.data[0].header["DEC"]] bb = prima.projBaseline(self.baseXYZ, self.radec, self.lst) if k == "base": self.var_mjd[k] = bb["B"] if debug: print "DEBUG: PBL12 START: computed", self.var_mjd[k][0], "in header:", self.data[0].header[ he + "ISS PBL12 START" ], "DELTA=", self.var_mjd[k][0] - self.data[0].header[he + "ISS PBL12 START"] print "DEBUG: PBL12 END : computed", self.var_mjd[k][-1], "in header:", self.data[0].header[ he + "ISS PBL12 END" ], "DELTA=", self.var_mjd[k][-1] - self.data[0].header[he + "ISS PBL12 END"] if k == "PA": self.var_mjd[k] = bb["PA"] if debug: print "DEBUG: PBLA12 START: computed", self.var_mjd[k][0], "in header:", self.data[0].header[ he + "ISS PBLA12 START" ], "DELTA=", self.var_mjd[k][0] - self.data[0].header[he + "ISS PBLA12 START"] print "DEBUG: PBLA12 END : computed", self.var_mjd[k][-1], "in header:", self.data[0].header[ he + "ISS PBLA12 END" ], "DELTA=", self.var_mjd[k][-1] - self.data[0].header[he + "ISS PBLA12 END"] self.data.close() return
def dOPDfunc(X, prms, addIntermediate=False): """ only works with one target, and one baselines X = [{'TARGET':, 'RA':, 'DEC':, 'B_XYZA':, 'lst', 'SWAPPED':, 'MJD'}] --------------------------------------------------------------------- - RA, DEC: the coordinates in decimal hour and degrees - B_XYZA is the baseline vector in meters (length 4) - LST in decimal hour - SWAPPED: 1, 0, or True, False possible parameters: -------------------- angles in degrees, separation in arcsec, M0 in mm - params: {'M0':, 'SEP':, 'PA':) - params: {'M0':, 'SEP':, 'PA':, 'M0S':} where M0S is the zero point in SWAPPED - params: {'M0 MJD xxxxxx.xxx xxxxxx.xxx', 'M0 MJD yyyyyy.yyyy yyyyyyy.yyy':, 'SEP':, 'PA':} with 2 different zero point, based on the MJD (the 2 MJD and the min and max range). Should be floats, no ints linear drift of separation: - 'SEP MJD xxxxxx.xx':arcsec, 'PA MJD xxxxxxxxx.xx':degree, 'LINDIR':degrees, 'LINRATE':uas/day 'SEP ...' and 'PA ...' defines the separation and PA at a given date. from there, the separation vector evolves at the given rate, in the given direction. - addIntermediate: stores intermediate calculations, such as projected baseline, separation, M0 etc. PRIMETphase counts when PRIMET has been initialized. Only point with same PRIMETphase can be combined. """ global dOPDfuncNiter c_ = np.pi / (180 * 3600.0) # rad / arcsec if len(X) < 1: # case nothing is passed return [] # start with 0 dOPD dOPD = np.zeros(len(X)) # we will need (-1)**swap a few time: swap = (-1) ** np.array([x["SWAPPED"] for x in X]) # compute projected baseline: projB = prima.projBaseline(X[0]["B_XYZA"], (X[0]["RA"], X[0]["DEC"]), [x["LST"] for x in X]) b_p = projB["B"] b_pa = projB["PA"] if addIntermediate: for k in range(len(X)): X[k]["fit Bp"] = b_p[k] X[k]["fit Bpa"] = b_pa[k] # single metrology zero point if prms.has_key("M0"): dOPD += prms["M0"] * 1e-3 if addIntermediate: for k in range(len(X)): X[k]["fit M0"] = prms["M0"] * 1e-3 X[k]["fit PRIMETphase"] = 0 # different zero point for SWAPPED and NORMAL if prms.has_key("M0S"): dOPD = np.array([prms["M0S"] * 1e-3 if x["SWAPPED"] else prms["M0"] for x in X]) if addIntermediate: for k in range(len(X)): X[k]["fit M0"] = prms["M0S"] * 1e-3 if X[k]["SWAPPED"] else prms["M0"] X[k]["fit PRIMETphase"] = 0 # still considered a single PRIMET phase # different M0 by MJD range if any([k[:6] == "M0 MJD" for k in prms.keys()]): mjd = np.array([x["MJD"] for x in X]) PRIMETphase = 0 for k in prms.keys(): if k[:6] == "M0 MJD": MJD_min = float(k.split()[2]) MJD_max = float(k.split()[3]) w = np.where((mjd < MJD_max) * (mjd >= MJD_min)) dOPD[w] = prms[k] * 1e-3 if addIntermediate: for k in range(len(w[0])): X[w[0][k]]["fit M0"] = dOPD[w][k] X[w[0][k]]["fit PRIMETphase"] = PRIMETphase PRIMETphase += 1 # astrometric modulation: static if prms.has_key("SEP") and prms.has_key("PA"): dOPD += swap * b_p * prms["SEP"] * c_ * np.cos((b_pa - prms["PA"]) * np.pi / 180) if addIntermediate: for k in range(len(X)): X[k]["fit SEP"] = prms["SEP"] X[k]["fit PA"] = prms["PA"] # astrometric modulation: linear if ( any(["SEP MJD" in k for k in prms.keys()]) and any(["PA MJD" in k for k in prms.keys()]) and prms.has_key("LINDIR") and prms.has_key("LINRATE") ): # get MJD0: for k in prms.keys(): if k[:7] == "SEP MJD": MJD0 = float(k.split()[2]) SEP0 = prms[k] if k[:6] == "PA MJD": PA0 = prms[k] # cartesian separation vector: X_ = SEP0 * np.sin(PA0 * np.pi / 180) Y_ = SEP0 * np.cos(PA0 * np.pi / 180) X_ += 1e-6 * (np.array([x["MJD"] for x in X]) - MJD0) * prms["LINRATE"] * np.sin(prms["LINDIR"] * np.pi / 180) Y_ += 1e-6 * (np.array([x["MJD"] for x in X]) - MJD0) * prms["LINRATE"] * np.cos(prms["LINDIR"] * np.pi / 180) # compute separation/PA as a function of time: SEPt = np.sqrt(X_ ** 2 + Y_ ** 2) PAt = np.arctan2(X_, Y_) * 180 / np.pi if addIntermediate: for k in range(len(X)): X[k]["fit SEP"] = SEPt[k] X[k]["fit PA"] = PAt[k] dOPD += swap * b_p * SEPt * c_ * np.cos((b_pa - PAt) * np.pi / 180) if prms.has_key("SEP"): # angle between M10 edge and the binary: addAngle = np.arcsin(10.0 / prms["SEP"]) * 180 / np.pi if prms["SEP"] > 10 else 90.0 addAngle += 90 # relative to x sx = prms["SEP"] * c_ * np.cos(addAngle / 180.0 * np.pi) # in rad sy = prms["SEP"] * c_ * np.sin(addAngle / 180.0 * np.pi) # in rad else: # angle between M10 edge and the binary: addAngle = np.arcsin(10.0 / SEP0) * 180 / np.pi if SEP0 > 10 else 90.0 addAngle += 90 # relative to x sx = SEP0 * c_ * np.cos(addAngle / 180.0 * np.pi) # in rad sy = SEP0 * c_ * np.sin(addAngle / 180.0 * np.pi) # in rad if addIntermediate: for k in range(len(X)): X[k]["fit angleIRIS"] = addAngle if prms.has_key("IRIS scale"): scale = prms["IRIS scale"] else: scale = 23.5e-3 # scale of pupil on IRIS, in m/pix if prms.has_key("ATPUP scale"): scale *= prms["ATPUP scale"] # pupil runout model #################### px = np.zeros(len(X)) py = np.zeros(len(X)) # -- parameters used in the formula Pfuhl = ["a0", "a1", "phi0", "phi1", "phi2", "x0", "y0"] Bonnet = ["ctX", "stX", "cdX", "sdX", "c2dX", "s2dX", "ctY", "stY", "cdY", "sdY", "c2dY", "s2dY"] Ts = ["3", "4"] for t in Ts: if all([prms.has_key("AT" + t + " " + p) for p in Pfuhl]): az = np.array([o["AZ" + t] for o in X]) rot = np.array([o["ROT" + t] for o in X]) # built dict of parameters tmp = {} for z in Pfuhl: tmp[z] = prms["AT" + t + " " + z] # compute error tmpX, tmpY = Pfuhl_pupilPxPy(rot, az, tmp) px = -tmpX # check sign! py = -tmpY # check sign! if all([prms.has_key("AT" + t + " " + p) for p in Bonnet]): az = np.array([o["AZ" + t] for o in X]) alt = np.array([o["ALT" + t] for o in X]) rot = np.array([o["ROT" + t] for o in X]) # built dict of parameters tmp = {} for z in Bonnet: tmp[z] = prms["AT" + t + " " + z] # compute error tmpX, tmpY = Bonnet_pupilPxPy(rot, alt, az, tmp) px += tmpX py += tmpY correctionPup = (px * sx + py * sy) * scale if addIntermediate: for k in range(len(X)): X[k]["fit PUPbias"] = correctionPup[k] dOPD += correctionPup #### done with pupil ############## ### finished ### dOPDfuncNiter += 1 if addIntermediate: for k in range(len(X)): X[k]["fit DOPD"] = dOPD[k] return X else: return dOPD
def OPDmodel(loadData=False, bin=10, do_fit=False): """ """ global opd_model_data try: print len(opd_model_data) except: loadData=True if loadData: files = ['2011-11-21/PACMAN_OBJ_ASTRO_326_00%s.fits'%(f) for f in ['04', '05', '06', '07', '08', '09', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20']] opd_model_data = [] for f in files: a = prima.drs(data_directory+f) opd_model_data.append(a.expectedOPD(bin=bin)) a = [] B = opd_model_data[0]['XYZ'] fit = np.array([1,1,1,1]) p_fit = np.array(B)[np.where(np.array(fit))] p_fixed = np.array(B)[np.where(1-np.array(fit))] obsN = filter(lambda x: x['INSMODE']=='NORMAL', opd_model_data) obsS = filter(lambda x: x['INSMODE']=='SWAPPED', opd_model_data) plsq = leastsq(leastsqOPDModel, p_fit, args=(fit, p_fixed, obsN), epsfcn=1e-3) Bf = np.array(B) Bf[np.where(fit)] = plsq[0] print np.array(B)-np.array(Bf) for x in opd_model_data: x['ORIGINAL']=prima.projBaseline(x['XYZA'], [x['RA'], x['DEC']], x['LST'])['opd']/x['AIRN']-x['DL2-DL1'] x['RESIDUALS']=prima.projBaseline(Bf, [x['RA'], x['DEC']], x['LST'])['opd']/x['AIRN']-x['DL2-DL1'] obsN = filter(lambda x: x['INSMODE']=='NORMAL', opd_model_data) obsS = filter(lambda x: x['INSMODE']=='SWAPPED', opd_model_data) obs = opd_model_data pyplot.figure(0) pyplot.clf() pyplot.subplot(221) pyplot.plot([x['AZ'] for x in obsN], [x['RESIDUALS'].mean() for x in obsN], 'ob', label='NORMAL') pyplot.plot([x['AZ'] for x in obsS], [x['RESIDUALS'].mean() for x in obsS], 'or', label='SWAPPED') pyplot.plot([x['AZ'] for x in obsN], [x['ORIGINAL'].mean() for x in obsN], '+b', label='NORMAL') pyplot.plot([x['AZ'] for x in obsS], [x['ORIGINAL'].mean() for x in obsS], '+r', label='SWAPPED') #pyplot.legend() pyplot.xlabel('AZ') pyplot.ylabel('residuals') pyplot.subplot(222) pyplot.plot([x['ALT'] for x in obsN], [x['RESIDUALS'].mean() for x in obsN], 'ob', label='NORMAL') pyplot.plot([x['ALT'] for x in obsS], [x['RESIDUALS'].mean() for x in obsS], 'or', label='SWAPPED') pyplot.plot([x['ALT'] for x in obsN], [x['ORIGINAL'].mean() for x in obsN], '+b', label='NORMAL') pyplot.plot([x['ALT'] for x in obsS], [x['ORIGINAL'].mean() for x in obsS], '+r', label='SWAPPED') #pyplot.legend() pyplot.xlabel('ALT') pyplot.ylabel('residuals') pyplot.subplot(223) pyplot.plot(range(len(obs)), [x['RESIDUALS'].mean() for x in obs], 'ok', label='NORMAL') pyplot.plot(range(len(obs)), [x['ORIGINAL'].mean() for x in obs], '+k', label='NORMAL') #pyplot.legend() pyplot.xlabel('N') pyplot.ylabel('residuals') return opd_model_data