def errVsRadius(root, epoch): # Get the star set info s = starset.StarSet(root) x = s.getArray('x') y = s.getArray('y') xerr = s.getArrayFromEpoch(epoch, 'xerr_a') yerr = s.getArrayFromEpoch(epoch, 'yerr_a') idx = (np.where(xerr > 0))[0] x = x[idx] y = y[idx] xerr = xerr[idx] * 1000.0 yerr = yerr[idx] * 1000.0 r = np.hypot(x, y) p.clf() p.semilogy(r, xerr, 'bx') p.semilogy(r, yerr, 'r+') p.axis([0, 5, 0.05, 5]) p.xlabel('Radius (arcsec)') p.ylabel('Alignment Error (mas)') p.title('Epoch #%d: %8.3f' % (epoch, s.stars[0].years[epoch])) p.savefig('plots/alignErrVsRadius.png')
def printLabelInfo(alignRoot, polyRoot, starName): # Now read in the align stuff s = starset.StarSet(alignRoot) s.loadPolyfit(polyRoot, accel=0) mag = s.getArray('mag') name = np.array(s.getArray('name')) x0 = s.getArray('fitXv.p') * -1.0 y0 = s.getArray('fitYv.p') x0err = s.getArray('fitXv.perr') y0err = s.getArray('fitYv.perr') vx = s.getArray('fitXv.v') * -1.0 vy = s.getArray('fitYv.v') vxerr = s.getArray('fitXv.verr') vyerr = s.getArray('fitYv.verr') t0x = s.getArray('fitXv.t0') t0y = s.getArray('fitYv.t0') r = np.hypot(x0, y0) # Fix x0err, y0err to some minimum value idx = np.where(x0err < 0.0001)[0] x0err[idx] = 0.0001 idx = np.where(y0err < 0.0001)[0] y0err[idx] = 0.0001 idx = np.where(name == starName)[0] if len(idx) > 0: rr = idx[0] print '%-11s %4.1f %6.3f %6.3f %7.4f %7.4f %8.3f %8.3f %7.3f %7.3f %8.3f 1 %5.3f' % \ (name[rr], mag[rr], x0[rr], y0[rr], x0err[rr], y0err[rr], vx[rr]*10**3, vy[rr]*10**3, vxerr[rr]*10**3, vyerr[rr]*10**3, t0x[rr], r[rr]) else: print 'Could not find star %s' % starName
def plot2d(root, epoch): s = starset.StarSet(root) x = s.getArray('x') y = s.getArray('y') xerr = s.getArrayFromEpoch(epoch, 'xerr_a') yerr = s.getArrayFromEpoch(epoch, 'yerr_a') idx = (np.where(xerr > 0))[0] x = x[idx] y = y[idx] xerr = xerr[idx] * 1000.0 yerr = yerr[idx] * 1000.0 p.clf() #p.quiver([x], [y], [xerr], [yerr], 0.4) scale = 3.0e2 p.scatter(x, y, xerr * scale, c='b', marker='o', alpha=0.5) p.scatter(x, y, yerr * scale, c='r', marker='s', alpha=0.5) p.scatter([-3.5], [-3.5], 0.5 * scale, c='k', marker='s') p.text(-3.1, -3.6, '0.5 mas') p.xlabel('X') p.ylabel('Y') p.title('Epoch #%d: %8.3f' % (epoch, s.stars[0].years[epoch])) p.savefig('plot/salignErr2D.png')
def plotDegreesOfFreedom(root='./', align='align/align_d_rms_t', poly='polyfit_d_points/fit', accel=False, youngOnly=False): s = starset.StarSet(root + align) s.loadPolyfit(root + poly, arcsec=1, accel=accel) if (youngOnly): s.onlyYoungDisk() if (accel): dof = s.getArray('fitXa.dof') else: dof = s.getArray('fitXv.dof') cnt = s.getArray('velCnt') dofBins = np.arange(0, cnt.max() + 1) py.clf() py.hist(dof, bins=dofBins, alpha=0.6) py.xlabel('Degrees of Freedom') py.ylabel('Number of Stars') py.title('%d stars in %d-%d epochs' % (len(cnt), cnt.min(), cnt.max())) py.savefig(root + 'plots/hist_degrees_of_freedom.png')
def go(epoch, limMag=15): root = '/u/ghezgroup/data/gc/' + epoch + '/clean/kp/starfinder/align/' aln_list = root + 'align_kp_0.0.list' #frameList = asciidata.open(aln_list) f_list = open(aln_list) files = [] for line in f_list: _line = line.split() fileParts = _line[0].split('/') files.append(fileParts[-1]) files = files[1:] #frames = frameList[0].tonumarray() s = starset.StarSet(root + 'align_kp_0.0') numstars = asciidata.open(root + 'align_kp_0.0.mag').nrows numepochs = asciidata.open(root + 'align_kp_0.0.mag').ncols - 5 fluxFile = root + '/sgra_all.mag' brtFile = root + '/sgra_brt.mag' dimFile = root + '/sgra_dim.mag' _sgraAll = open(fluxFile, 'w') _sgraBrt = open(brtFile, 'w') _sgraDim = open(dimFile, 'w') _sgraAll.write('#Frame' + ' Mag ' + ' Flux(mJy) ' + '\n') _sgraBrt.write('#Frame' + ' Mag ' + ' Flux(mJy) ' + '\n') _sgraDim.write('#Frame' + ' Mag ' + ' Flux(mJy) ' + '\n') # Find index for Sgr A* in the mag file for x in range(numstars): if (s.stars[x].name == 'SgrA'): sgra_idx = x # Loop through epochs and print frame, mags, & fluxes (in mJy) for i in range(numepochs): mag = s.stars[sgra_idx].e[i].mag flux = 655000. * 10**(-0.4 * mag) #frame = frames[i] frame = files[i] _sgraAll.write('%5s % 5.3f %7.2f\n' % (frame, mag, flux)) if (mag < limMag): _sgraBrt.write('%5s % 5.3f %7.2f\n' % (frame, mag, flux)) else: _sgraDim.write('%5s % 5.3f %7.2f\n' % (frame, mag, flux)) _sgraAll.close() _sgraBrt.close() _sgraDim.close()
def process_align_output(alignRoot): """ Read in align output, store in a starset, and save in a digital format for fast reading in the future. """ print "Fetching lists, dates, and integration times." roots, quads, dates, tints = Starlist.read_align_list(alignRoot) print "Reading in align output." s = starset.StarSet(alignRoot) x = s.getArrayFromAllEpochs('x') y = s.getArrayFromAllEpochs('y') m = s.getArrayFromAllEpochs('mag') print "Processing align output." # Save the first epoch as a reference. xref = x[0,:] yref = y[0,:] mref = m[0,:] # Drop the first epoch, a reference. x = x[1:,:] y = y[1:,:] m = m[1:,:] name = s.getArray('name') ndet = np.array(s.getArray('velCnt'), dtype=np.int16) # Set up mask to get rid of invalid values idx = x <= -1e5 # For performance reasons, convert to dx and dy # and store in smaller array format. dx = np.array(x - xref, dtype=np.float32) dy = np.array(y - yref, dtype=np.float32) m = np.array(m, dtype=np.float16) # Create masked arrays dxm = np.ma.masked_where(idx, dx) dym = np.ma.masked_where(idx, dy) mm = np.ma.masked_where(idx, m) _out = open(alignRoot + '_xym.pickle', 'w') pickle.dump(name, _out) pickle.dump(ndet, _out) pickle.dump(xref, _out) pickle.dump(yref, _out) pickle.dump(mref, _out) pickle.dump(dxm, _out) pickle.dump(dym, _out) pickle.dump(mm, _out) pickle.dump(roots, _out) pickle.dump(quads, _out) pickle.dump(dates, _out) pickle.dump(tints, _out) _out.close()
def plotFitRms(root, polyroot, gcfitdir): s = starset.StarSet(root) s.loadPolyfit(polyroot, arcsec=1, accel=0) years = s.stars[0].years fitPx = s.getArray('fitXv.p') fitVx = s.getArray('fitXv.v') fitPy = s.getArray('fitYv.p') fitVy = s.getArray('fitYv.v') t0x = s.getArray('fitXv.t0') t0y = s.getArray('fitYv.t0') rmsX = na.zeros(len(s.stars), type=na.Float) rmsY = na.zeros(len(s.stars), type=na.Float) rms = na.zeros(len(s.stars), type=na.Float) cnt = na.zeros(len(s.stars), type=na.Int) for ee in range(len(years)): dtX = years[ee] - t0x dtY = years[ee] - t0y xfit = fitPx + (dtX * fitVx) yfit = fitPy + (dtY * fitVy) x = s.getArrayFromEpoch(ee, 'x') y = s.getArrayFromEpoch(ee, 'y') xpix = s.getArrayFromEpoch(ee, 'xpix') ypix = s.getArrayFromEpoch(ee, 'ypix') diffx = xfit - x diffy = yfit - y diff = na.sqrt(diffx**2 + diffy**2) idx = (na.where(xpix > -999))[0] rmsX[idx] += diffx**2 rmsY[idx] += diffy**2 rms[idx] += diff**2 cnt[idx] += 1 rmsX = na.sqrt(rmsX / cnt) * 1000.0 rmsY = na.sqrt(rmsY / cnt) * 1000.0 rms = na.sqrt(rms / cnt) * 1000.0 mag = s.getArray('mag') x = s.getArray('x') y = s.getArray('y') r = na.sqrt(x**2 + y**2) idx = (na.where(mag < 15))[0] p.clf() p.semilogy(r[idx], rms[idx], 'k.')
def align_res(target, date, prefix='a', Kcut=18, weight=4, transform=4, export=False, root='/u/nijaid/work/', main_out='/u/nijaid/microlens/paper_plots/'): work_dir = root + target.upper() + '/' + prefix + '_' + date + '/' align_dir = work_dir + prefix + '_' + target + '_' + date + '_a' + str( transform) + '_m' + str(Kcut) + '_w' + str(weight) + '_MC100/' s = starset.StarSet(align_dir + 'align/align_t') s.loadPolyfit(align_dir + 'polyfit_d/fit', accel=0, arcsec=0) names = s.getArray('name') i = names.index(target) star = s.stars[i] pointsTab = Table.read(align_dir + 'points_d/' + target + '.points', format='ascii') time = np.array(pointsTab[pointsTab.colnames[0]]) x = pointsTab[pointsTab.colnames[1]] y = pointsTab[pointsTab.colnames[2]] xerr = pointsTab[pointsTab.colnames[3]] * 9.95 yerr = pointsTab[pointsTab.colnames[4]] * 9.95 fitx = star.fitXv fity = star.fitYv dt = time - fitx.t0 fitLineX = fitx.p + (fitx.v * dt) fitLineY = fity.p + (fity.v * dt) resX = (x - fitLineX) * 9.95 resY = (y - fitLineY) * 9.95 fmt = '{0:.3f}: dx = {1:6.3f} dy = {2:6.3f} xe = {3:6.3f} ye = {3:6.3f}' for yy in range(len(time)): print(fmt.format(time[yy], resX[yy], resY[yy], xerr[yy], yerr[yy])) if export: out_dir = main_out + 'align_res_' + target + '_' + date + '_a' + str( transform) + '_m' + str(Kcut) + '_w' + str(weight) _out = open(out_dir + '.txt', 'w') pfmt = fmt + '\n' for yy in range(len(time)): _out.write( pfmt.format(time[yy], resX[yy], resY[yy], xerr[yy], yerr[yy])) _out.close()
def plotVelocityMap(root='./', align='align/align_d_rms_1000_abs_t', poly='polyfit_d/fit'): s = starset.StarSet(root + align) s.loadPolyfit(root + poly) x = s.getArray('fitXv.p') y = s.getArray('fitYv.p') vx = s.getArray('fitXv.v') vy = s.getArray('fitYv.v') py.clf() arrScale = 1.0 py.quiver([x], [y], [vx], [vy], scale=0.35, headwidth=3, color='black')
def velocityAverage(alignRoot, polyRoot, magCut=15): """ Calculate the mean (and error on mean) of the velocities from a align/polyfit. Input Parameters: -- the root name of the align output (e.g. 'align/align_d_rms_t' -- the root name of the polyfit output( e.g. 'polyfit_d/fit') """ # This should be an absolute aligned data set. cc = objects.Constants() s = starset.StarSet(alignRoot) s.loadPolyfit(polyRoot, accel=0) vx = s.getArray('fitXv.v') * 10**3 vy = s.getArray('fitYv.v') * 10**3 vxerr = s.getArray('fitXv.verr') * 10**3 vyerr = s.getArray('fitYv.verr') * 10**3 mag = s.getArray('mag') idx = np.where(mag <= magCut)[0] py.clf() py.hist(vx[idx]) py.hist(vy[idx]) print 'Number of Stars: %d' % len(idx) print 'X Mean Velocity: %5.2f' % (vx[idx].mean()) print 'X Error on Mean: %5.2f' % (vx[idx].std() / math.sqrt(len(vx))) print 'Y Mean Velocity: %5.2f' % (vy[idx].mean()) print 'Y Error on Mean: %5.2f' % (vy[idx].std() / math.sqrt(len(vx))) # Plot distribution of velocity errors py.clf() binsIn = np.arange(0, max([max(vxerr), max(vyerr)]), 0.1) (bins, data) = histNofill.hist(binsIn, vxerr) py.plot(bins, data, 'r', linewidth=2) (bins, data) = histNofill.hist(binsIn, vyerr) py.plot(bins, data, 'b', linewidth=2) py.axis([0, 10, 0, 600]) py.xlabel('Velocity Errors (mas/yr)') py.ylabel('N') py.savefig('plots/histVelErr.png')
def confusionThreshold(starName1, starName2, root='./', align='align/align_d_rms1000_t', poly='polyfit_d/fit'): s = starset.StarSet(root + align) s.loadPolyfit(root + poly, arcsec=1, accel=0) names = s.getArray('name') id1 = names.index(starName1) id2 = names.index(starName2) star1 = s.stars[id1] star2 = s.stars[id2] years = np.array(star1.years) xfit1 = star1.fitXv.p + (star1.fitXv.v * (years - star1.fitXv.t0)) yfit1 = star1.fitYv.p + (star1.fitYv.v * (years - star1.fitYv.t0)) xfit2 = star2.fitXv.p + (star2.fitXv.v * (years - star2.fitXv.t0)) yfit2 = star2.fitYv.p + (star2.fitYv.v * (years - star2.fitYv.t0)) xdiff = xfit1 - xfit2 ydiff = yfit1 - yfit2 diff = hypot(xdiff, ydiff) for ee in range(len(years)): detected1 = (star1.e[ee].xpix > -999) detected2 = (star2.e[ee].xpix > -999) if (diff[ee] < 0.075): print '%8.3f Close Approach: sep = %5.3f' % \ (years[ee], diff[ee]) if ((detected1 == False) and (detected2 == False)): print '\tNeither source found... do nothing' if ((detected1 == False) and (detected2 == True)): print '\t%13s: Not found in this epoch' % (starName1) print '\t%13s: Remove point for this epoch' % (starName2) if ((detected2 == False) and (detected1 == True)): print '\t%13s: Not found in this epoch' % (starName2) print '\t%13s: Remove point for this epoch' % (starName1) if ((detected1 == True) and (detected2 == True)): print '\t Found both sources... do nothing'
def updateLabelInfoWithDeepMosaic(oldLabelFile, dpMscAlignDir, outputFile, alignRoot='align/align_d_rms_100_abs_t', polyRoot='polyfit_100/fit'): """ Modify an existing label.dat file with updated positions, velocities, and magnitudes from a dp_msc alignment. Input Parameters: oldLabelFile - The name of the input old label.dat file dpMscAlignDir - the root directory name of a dp_msc alignment and polyfit (e.g. /u/jlu/work/gc/do_msc/2011_05_29/) outputFile - Save the modified label.dat content to a new file. """ old = Labels(oldLabelFile) s = starset.StarSet(dpMscAlign + alignRoot) s.loadPolyfit(dpMscAlign + polyRoot, accel=0)
def plot_vpd_align(alignRoot, epoch1, epoch2, outRoot='plot_align'): """ Read in an aligned data set. Plot a vector-point-diagram for the positional differences between two different epochs within the data set. """ s = starset.StarSet(alignRoot) x1 = s.getArrayFromEpoch(epoch1, 'xorig') y1 = s.getArrayFromEpoch(epoch1, 'yorig') x2 = s.getArrayFromEpoch(epoch2, 'xorig') y2 = s.getArrayFromEpoch(epoch2, 'yorig') x1e = s.getArrayFromEpoch(epoch1, 'xpixerr_p') y1e = s.getArrayFromEpoch(epoch1, 'ypixerr_p') x2e = s.getArrayFromEpoch(epoch2, 'xpixerr_p') y2e = s.getArrayFromEpoch(epoch2, 'ypixerr_p') dx = x2 - x1 dy = y2 - y1 dxe = np.hypot(x1e, x2e) dye = np.hypot(y1e, y2e) dr = np.hypot(dx, dy) idx = np.where((dxe < 0.02) & (dye < 0.02) & (dr < 3.0))[0] print len(x1), len(idx) drmax = 1.5 py.figure(1) py.clf() py.plot(dx[idx], dy[idx], 'k.', ms=2) py.xlabel('Delta X (pixels)') py.ylabel('Delta Y (pixels)') py.axis([-drmax, drmax, -drmax, drmax]) py.savefig(outRoot + '_vpd.png') py.figure(2) py.clf() q = py.quiver(x1[idx], y1[idx], dx[idx], dy[idx], scale=10) py.quiverkey(q, 0.5, 0.95, 0.05, '0.05 pix', color='red') py.savefig(outRoot + '_dr_vec.png')
def CompareTarget(TargetName, root='./', align='align/align_d_rms_1000_abs_t', poly='polyfit_d/fit', useAccFits=False): s = starset.StarSet(rootDir + align) s.loadPolyfit(rootDir + poly, accel=0, arcsec=0) names = s.getArray('name') indTarg = names.index(TargetName) star = s.stars[indTarg] pointsFile = root + points + TargetName + '.points' if os.path.exists(pointsFile + '.orig'): pointsTab = Table.read(pointsFile + '.orig', format='ascii') else: pointsTab = Table.read(pointsFile, format='ascii') # Observed Data time = pointsTab[pointsTab.colnames[0]] x = pointsTab[pointsTab.colnames[1]] y = pointsTab[pointsTab.colnames[2]] xerr = pointsTab[pointsTab.colnames[3]] yerr = pointsTab[pointsTab.colnames[4]] fitx = star.fitXv fity = star.fitYv dt = time - fitx.t0 fitLineX = fitx.p + (fitx.v * dt) fitSigX = np.sqrt(fitx.perr**2 + (dt * fitx.verr)**2) fitLineY = fity.p + (fity.v * dt) fitSigY = np.sqrt(fity.perr**2 + (dt * fity.verr)**2) resTargX = x - fitLineX resTargY = y - fitliney diffEpX, diffEpY = sigmaVsEpoch(root=root, align=align, poly=poly, useAccFits=useAccFits)
def errVsMag(root, epoch): # Get the star set info s = starset.StarSet(root) xerr = s.getArrayFromEpoch(epoch, 'xerr_a') yerr = s.getArrayFromEpoch(epoch, 'yerr_a') mag = s.getArray('mag') idx = (np.where(xerr > 0))[0] mag = mag[idx] xerr = xerr[idx] * 1000.0 yerr = yerr[idx] * 1000.0 p.clf() p.semilogy(mag, xerr, 'bx') p.semilogy(mag, yerr, 'r+') p.axis([8, 17, 0.05, 5]) p.xlabel('Magnitude') p.ylabel('Alignment Error (mas)') p.title('Epoch #%d: %8.3f' % (epoch, s.stars[0].years[epoch])) p.savefig('plots/alignErrVsMag.png')
def plotVsMag(root='./', align='align/align_d_rms_t', poly='polyfit_d_points/fit', youngOnly=False, showLabels=False): # Load up our starlist s = starset.StarSet(root + align) s.loadPolyfit(root + poly, accel=0, arcsec=1) if (youngOnly): s.onlyYoungDisk() chiXred = s.getArray('fitXv.chi2red') chiYred = s.getArray('fitYv.chi2red') mag = s.getArray('mag') names = s.getArray('name') py.clf() py.subplot(2, 1, 1) py.plot(mag, chiXred, 'k^') py.xlabel('Magniutde') py.ylabel('X Reduced Chi-Sq') if (showLabels): for ii in range(len(names)): py.text(mag[ii], chiXred[ii], names[ii]) py.ylim(0, 100) py.subplot(2, 1, 2) py.plot(mag, chiYred, 'k^') py.xlabel('Magniutde') py.ylabel('Y Reduced Chi-Sq') if (showLabels): for ii in range(len(names)): py.text(mag[ii], chiYred[ii], names[ii]) py.ylim(0, 100)
def align_plot(root_dir='./', align_root='align'): s = starset.StarSet(root_dir + align_root) s.loadStarsUsed() x = s.getArrayFromAllEpochs('xpix') y = s.getArrayFromAllEpochs('ypix') xe_p = s.getArrayFromAllEpochs('xpixerr_p') ye_p = s.getArrayFromAllEpochs('ypixerr_p') xe_a = s.getArrayFromAllEpochs('xpixerr_a') ye_a = s.getArrayFromAllEpochs('ypixerr_a') isUsed = s.getArrayFromAllEpochs('isUsed') x0 = s.getArray('fitpXv.p') y0 = s.getArray('fitpYv.p') vx = s.getArray('fitpXv.v') vy = s.getArray('fitpYv.v') t0x = s.getArray('fitpXv.t0') t0y = s.getArray('fitpYv.t0') m = s.getArray('mag') cnt = s.getArray('velCnt') N_epochs = x.shape[0] N_stars = x.shape[1] # Setup arrays xresid_rms_all = np.zeros(N_epochs, dtype=float) yresid_rms_all = np.zeros(N_epochs, dtype=float) xresid_rms_used = xresid_rms_all yresid_rms_used = xresid_rms_all xresid_err_a_all = xresid_rms_all yresid_err_a_all = xresid_rms_all xresid_err_a_used = xresid_rms_all yresid_err_a_used = xresid_rms_all xresid_err_p_all = xresid_rms_all yresid_err_p_all = xresid_rms_all xresid_err_p_used = xresid_rms_all yresid_err_p_used = xresid_rms_all chi2x_all = xresid_rms_all chi2y_all = xresid_rms_all chi2x_used = xresid_rms_all chi2y_used = xresid_rms_all N_stars_all = xresid_rms_all N_stars_used = xresid_rms_all year = xresid_rms_all idx = np.where(cnt > 2)[0] N_stars_3ep = len(idx) for ee in range(N_epochs): idx = np.where((cnt > 2) & (x[ee, :] > -1000) & (xe_p[ee, :] > 0))[0] used = np.where(isUsed[ee, idx] == True) # Everything below should be arrays sub-indexed by "idx" dt_x = s.years[ee] - t0x[idx] dt_y = s.years[ee] - t0y[idx] x_fit = x0[idx] + (vx[idx] * dt_x) y_fit = y0[idx] + (vy[idx] * dt_y) xresid = x[ee, idx] - x_fit yresid = y[ee, idx] - y_fit N_stars_all[ee] = len(xresid) N_stars_used[ee] = len(xresid[used]) # Note this chi^2 only includes positional errors. chi2x_terms = xresid**2 / xe_p[ee, idx]**2 chi2y_terms = yresid**2 / ye_p[ee, idx]**2 xresid_rms_all[ee] = np.sqrt(np.mean(xresid**2)) yresid_rms_all[ee] = np.sqrt(np.mean(yresid**2)) xresid_rms_used[ee] = np.sqrt(np.mean(xresid[used]**2)) yresid_rms_used[ee] = np.sqrt(np.mean(yresid[used]**2)) xresid_err_p_all[ee] = xe_p[ee, idx].mean() / N_stars_all[ee]**0.5 yresid_err_p_all[ee] = ye_p[ee, idx].mean() / N_stars_all[ee]**0.5 xresid_err_p_used[ee] = xe_p[ee, idx][used].mean() / N_stars_used[ee]**0.5 yresid_err_p_used[ee] = ye_p[ee, idx][used].mean() / N_stars_used[ee]**0.5 xresid_err_a_all[ee] = xe_a[ee, idx].mean() / N_stars_all[ee]**0.5 yresid_err_a_all[ee] = ye_a[ee, idx].mean() / N_stars_all[ee]**0.5 xresid_err_a_used[ee] = xe_a[ee, idx][used].mean() / N_stars_used[ee]**0.5 yresid_err_a_used[ee] = ye_a[ee, idx][used].mean() / N_stars_used[ee]**0.5 chi2x_all[ee] = chi2x_terms.sum() chi2y_all[ee] = chi2y_terms.sum() chi2x_used[ee] = chi2x_terms[used].sum() chi2y_used[ee] = chi2y_terms[used].sum() year[ee] = s.years[ee] data = { 'xres_rms_all': xresid_rms_all, 'yres_rms_all': yresid_rms_all, 'xres_rms_used': xresid_rms_used, 'yres_rms_used': yresid_rms_used, 'xres_err_p_all': xresid_err_p_all, 'yres_err_p_all': yresid_err_p_all, 'xres_err_p_used': xresid_err_p_used, 'yres_err_p_used': yresid_err_p_used, 'xres_err_a_all': xresid_err_a_all, 'yres_err_a_all': yresid_err_a_all, 'xres_err_a_used': xresid_err_a_used, 'yres_err_a_used': yresid_err_a_used, 'chi2x_all': chi2x_all, 'chi2y_all': chi2y_all, 'chi2x_used': chi2x_used, 'chi2y_used': chi2y_used, 'N_stars_all': N_stars_all, 'N_stars_used': N_stars_used, 'year': year, 'N_stars_3ep': N_stars_3ep } return data
def makeLabelDat(oldLabelFile, root='./', align='align/align_t', poly='polyfit_d/fit', addNewStars=True, keepOldStars=True, updateStarPosVel=True, newUse=0, rad_cut=None, stars=None, newLabelFile='label_new.dat'): """ Make a new label.dat file using output from align and polyfit. Optional Inputs: root: The root of align analysis (e.g. './' or '07_05_18.') align: The root filename of the align output. poly: The root filename of the polyfit output. stars: A starset.StarSet() object with polyfit already loaded. This overrides align/poly/root values and is useful for custom cuts that trim_align can't handle such as magnitude dependent velocity error cuts. BEWARE: stars may be modified. Outputs: source_list/label_new.dat Dependencies: Polyfit and align must contain the same numbers/names of stars. Also, making the label.dat file depends on having the absolute astrometry done correctly. See gcwork.starset to learn about how the absolute astrometry is loaded (it depends on a specific reference epoch in align). You MUST run this on something that has already been run through java align_absolute. """ from gcwork import starset if stars == None: s = starset.StarSet(root + align) if (poly != None): s.loadPolyfit(root + poly) s.loadPolyfit(root + poly) else: s = stars # Trim out the new stars if we aren't going to add them if not addNewStars: idx = [] for ss in range(len(s.stars)): if 'star' not in s.stars[ss].name: idx.append(ss) s.stars = [s.stars[ss] for ss in idx] # Get the 2D radius of all stars and sort radius = s.getArray('r2d') ridx = radius.argsort() s.stars = [s.stars[ss] for ss in ridx] # Get info for all the stars. names = np.array(s.getArray('name')) if poly != None: t0 = s.getArray('fitXv.t0') x = s.getArray('fitXv.p') * -1.0 y = s.getArray('fitYv.p') xerr = s.getArray('fitXv.perr') yerr = s.getArray('fitYv.perr') vx = s.getArray('fitXv.v') * 995.0 * -1.0 vy = s.getArray('fitYv.v') * 995.0 vxerr = s.getArray('fitXv.verr') * 995.0 vyerr = s.getArray('fitYv.verr') * 995.0 else: t0 = s.getArray('fitXalign.t0') x = s.getArray('fitXalign.p') * -1.0 y = s.getArray('fitYalign.p') xerr = s.getArray('fitXalign.perr') yerr = s.getArray('fitYalign.perr') vx = s.getArray('fitXalign.v') * 995.0 * -1.0 vy = s.getArray('fitYalign.v') * 995.0 vxerr = s.getArray('fitXalign.verr') * 995.0 vyerr = s.getArray('fitYalign.verr') * 995.0 x -= x[0] y -= y[0] r2d = np.sqrt(x**2 + y**2) mag = s.getArray('mag') # Fix Sgr A* idx = np.where(names == 'SgrA')[0] if (len(idx) > 0): x[idx] = 0 y[idx] = 0 vx[idx] = 0 vy[idx] = 0 vxerr[idx] = 0 vyerr[idx] = 0 r2d[idx] = 0 # Clean up xerr and yerr so that they are at least 1 mas idx = np.where(xerr < 0.00001)[0] xerr[idx] = 0.00001 idx = np.where(yerr < 0.00001)[0] yerr[idx] = 0.00001 ########## # Load up the old star list and find the starting # point for new names. ########## oldLabels = Labels(labelFile=oldLabelFile) alnLabels = Labels(labelFile=oldLabelFile) newLabels = Labels(labelFile=oldLabelFile) if addNewStars: newNumber = calcNewNumbers(oldLabels.name, names) # Sort the old label list by radius just in case it # isn't already. We will update the radii first since # these sometimes get out of sorts. oldLabels.r = np.hypot(oldLabels.x, oldLabels.y) sidx = oldLabels.r.argsort() oldLabels.take(sidx) # Clean out the new label lists. newLabels.ourName = [] newLabels.name = [] newLabels.mag = [] newLabels.x = [] newLabels.y = [] newLabels.xerr = [] newLabels.yerr = [] newLabels.vx = [] newLabels.vy = [] newLabels.vxerr = [] newLabels.vyerr = [] newLabels.t0 = [] newLabels.useToAlign = [] newLabels.r = [] # Load up the align info into the alnLabels object alnLabels.ourName = names alnLabels.name = names alnLabels.mag = mag alnLabels.x = x alnLabels.y = y alnLabels.xerr = xerr alnLabels.yerr = yerr alnLabels.vx = vx alnLabels.vy = vy alnLabels.vxerr = vxerr alnLabels.vyerr = vyerr alnLabels.t0 = t0 alnLabels.r = r2d def addStarFromAlign(alnLabels, ii, use): newLabels.ourName.append(alnLabels.ourName[ii]) newLabels.name.append(alnLabels.name[ii]) newLabels.mag.append(alnLabels.mag[ii]) newLabels.x.append(alnLabels.x[ii]) newLabels.y.append(alnLabels.y[ii]) newLabels.xerr.append(alnLabels.xerr[ii]) newLabels.yerr.append(alnLabels.yerr[ii]) newLabels.vx.append(alnLabels.vx[ii]) newLabels.vy.append(alnLabels.vy[ii]) newLabels.vxerr.append(alnLabels.vxerr[ii]) newLabels.vyerr.append(alnLabels.vyerr[ii]) newLabels.t0.append(alnLabels.t0[ii]) newLabels.useToAlign.append(use) newLabels.r.append(alnLabels.r[ii]) def addStarFromOldLabels(oldLabels, ii): newLabels.ourName.append(oldLabels.name[ii]) newLabels.ourName.append(oldLabels.ourName[ii]) newLabels.name.append(oldLabels.name[ii]) newLabels.mag.append(oldLabels.mag[ii]) newLabels.x.append(oldLabels.x[ii]) newLabels.y.append(oldLabels.y[ii]) newLabels.xerr.append(oldLabels.xerr[ii]) newLabels.yerr.append(oldLabels.yerr[ii]) newLabels.vx.append(oldLabels.vx[ii]) newLabels.vy.append(oldLabels.vy[ii]) newLabels.vxerr.append(oldLabels.vxerr[ii]) newLabels.vyerr.append(oldLabels.vyerr[ii]) newLabels.t0.append(oldLabels.t0[ii]) newLabels.useToAlign.append(oldLabels.useToAlign[ii]) newLabels.r.append(oldLabels.r[ii]) def deleteFromAlign(alnLabels, idx): # Delete them from the align lists. alnLabels.ourName = np.delete(alnLabels.ourName, idx) alnLabels.name = np.delete(alnLabels.name, idx) alnLabels.mag = np.delete(alnLabels.mag, idx) alnLabels.x = np.delete(alnLabels.x, idx) alnLabels.y = np.delete(alnLabels.y, idx) alnLabels.xerr = np.delete(alnLabels.xerr, idx) alnLabels.yerr = np.delete(alnLabels.yerr, idx) alnLabels.vx = np.delete(alnLabels.vx, idx) alnLabels.vy = np.delete(alnLabels.vy, idx) alnLabels.vxerr = np.delete(alnLabels.vxerr, idx) alnLabels.vyerr = np.delete(alnLabels.vyerr, idx) alnLabels.t0 = np.delete(alnLabels.t0, idx) alnLabels.r = np.delete(alnLabels.r, idx) # Radial cut if rad_cut != None: cut = [] for rr in range(len(alnLabels.name)): if alnLabels.r[rr] > rad_cut: cut.append(rr) deleteFromAlign(alnLabels, cut) nn = 0 while nn < len(oldLabels.name): # # First see if there are any new stars that should come # before this star. # if addNewStars: def filterFunction(i): return (alnLabels.r[i] < oldLabels.r[nn]) and ('star' in alnLabels.name[i]) idx = filter(filterFunction, range(len(alnLabels.name))) for ii in idx: rAnnulus = int(math.floor(alnLabels.r[ii])) number = newNumber[rAnnulus] alnLabels.name[ii] = 'S%d-%d' % (rAnnulus, number) newNumber[rAnnulus] += 1 # Insert these new stars. addStarFromAlign(alnLabels, ii, newUse) # Delete these stars from the align info. deleteFromAlign(alnLabels, idx) # # Now look for this star in the new align info # idx = np.where(alnLabels.name == oldLabels.name[nn])[0] if len(idx) > 0: # Found the star if updateStarPosVel: # Update with align info addStarFromAlign(alnLabels, idx[0], oldLabels.useToAlign[nn]) else: # Don't update with align info addStarFromOldLabels(oldLabels, nn) deleteFromAlign(alnLabels, idx[0]) elif keepOldStars: # Did not find the star. Only keep if user said so. addStarFromOldLabels(oldLabels, nn) nn += 1 # Add the rest for gg in range(len(alnLabels.name)): addStarFromAlign(alnLabels, gg, newUse) # Quick verification that we don't have repeated names. uniqueNames = np.unique(newLabels.name) if len(uniqueNames) != len(newLabels.name): print('Problem, we have a repeat name!!') # Write to output newLabels.saveToFile(root + 'source_list/' + newLabelFile)
def accuracyFromResiduals(radiusCut=4): rootDir = '/u/jlu/work/gc/proper_motion/align/09_06_01/' alignRoot = 'align/align_d_rms_1000_abs_t' polyRoot = 'polyfit_d/fit' pointsRoot = 'points_d/' # Load starset s = starset.StarSet(rootDir + alignRoot) s.loadPolyfit(rootDir + polyRoot, accel=0, arcsec=0) # Keep only those stars in ALL epochs epochCnt = s.getArray('velCnt') idx = np.where(epochCnt == epochCnt.max())[0] newstars = [] for i in idx: newstars.append(s.stars[i]) s.stars = newstars mag = s.getArray('mag') x = s.getArray('x') y = s.getArray('y') r = np.hypot(x, y) # Trim on radius if (radiusCut != None): idx = np.where(r < radiusCut)[0] newstars = [] for i in idx: newstars.append(s.stars[i]) s.stars = newstars mag = mag[idx] x = x[idx] y = y[idx] r = r[idx] # Define some arrays we will keep. numStars = len(s.stars) medErrX = np.zeros(numStars, dtype=float) medErrY = np.zeros(numStars, dtype=float) medErr = np.zeros(numStars, dtype=float) medResX = np.zeros(numStars, dtype=float) medResY = np.zeros(numStars, dtype=float) medRes = np.zeros(numStars, dtype=float) for ss in range(numStars): star = s.stars[ss] starName = star.name pointsFile = rootDir + pointsRoot + starName + '.points' pointsTab = asciidata.open(pointsFile) # Observed Data t = pointsTab[0].tonumpy() x = pointsTab[1].tonumpy() y = pointsTab[2].tonumpy() xerr = pointsTab[3].tonumpy() yerr = pointsTab[4].tonumpy() # Best fit velocity model fitx = star.fitXv fity = star.fitYv dt = t - fitx.t0 fitLineX = fitx.p + (fitx.v * dt) fitLineY = fity.p + (fity.v * dt) # Residuals diffx = x - fitLineX diffy = y - fitLineY diff = np.hypot(diffx, diffy) medErrX[ss] = np.median(xerr) medErrY[ss] = np.median(yerr) medErr[ss] = np.median((xerr + yerr) / 2.0) medResX[ss] = np.median(diffx) medResY[ss] = np.median(diffy) medRes[ss] = np.median(diff) # Convert into milliarcsec medErrX *= 10**3 medErrY *= 10**3 medErr *= 10**3 medResX *= 10**3 medResY *= 10**3 medRes *= 10**3 # Bins stars vs. magnitude magStep = 1.0 magBins = np.arange(10.0, 20.0, magStep) medErrMag = np.zeros(len(magBins), dtype=float) medResMag = np.zeros(len(magBins), dtype=float) for mm in range(len(magBins)): mMin = magBins[mm] - (magStep / 2.0) mMax = magBins[mm] + (magStep / 2.0) idx = np.where((mag >= mMin) & (mag < mMax))[0] if (len(idx) > 0): medErrMag[mm] = np.median(medErr[idx]) medResMag[mm] = np.median(medRes[idx]) # Plot outdir = '/u/jlu/work/gc/astrometry/lgsao/plots/' py.clf() py.semilogy(magBins, medErrMag) py.semilogy(magBins, medResMag) py.legend(('Precision', 'Accuracy')) py.title('Keck AO Relative Astrometry') py.xlabel('K Magnitude for r < %4.1f"' % radiusCut) py.ylabel('Pos. Uncertainty (mas)') py.savefig(outdir + 'accuracy_from_residuals_log.png') py.clf() py.plot(magBins, medErrMag) py.plot(magBins, medResMag) py.legend(('Precision', 'Accuracy')) py.title('Keck AO Relative Astrometry') py.xlabel('K Magnitude for r < %4.1f"' % radiusCut) py.ylabel('Pos. Uncertainty (mas)') py.ylim(0, 2.0) py.savefig(outdir + 'accuracy_from_residuals_lin.png') foo = np.where((mag >= 11) & (mag <= 14))[0] print 'Median Precisions for K=11-14: ', np.median(medErr[foo]) print 'Median Accuracy for K=11-14: ', np.median(medRes[foo]) _logfile = open(outdir + 'accuracy_from_residuals.log', 'w') _logfile.write('Median Precisions for K=11-14: %5.2f\n' % np.median(medErr[foo])) _logfile.write('Median Accuracy for K=11-14: %5.2f\n' % np.median(medRes[foo])) _logfile.close()
def labelRestrict(inputLabel, outputLabel, alignInput, numSpeck=None, numAO=None): """ Modify an existing label.dat file to be used with the align -restrict flag. This is the program that chooses which stars are to be used for speckle alignment and which are to be used for AO alignment. The stars are chosen based on the number of detections in either speckle or AO. We will use the subset of stars in ALL speckle epochs as speckle alignment sources; and those stars that are in ALL AO epochs are used as AO alignment sources. The input align files should not have been trimmed for the most part. Be sure that there is an <alignInput>.list file containing the epochs and their data types. Paramters: inputLabel -- the input label.dat file. This will not be modified. outputLabel -- the output label.dat file. Only the use? column is changed. alignInput -- the root name of the align files to be used when determining how many speckle and AO maps a stars is found in. numSpeck -- if None then only stars in ALL speckle epochs are used as alignment sources. numAO -- if None then only stars in ALL AO epochs are used as alignment sources. """ from gcwork import starset labels = Labels(labelFile=inputLabel) s = starset.StarSet(alignInput) # Figure out the data/camera type for each epoch (speckle or AO) _list = open(alignInput + '.list', 'r') aoEpochs = [] spEpochs = [] i = 0 for line in _list: info = line.split() aoType = int(info[1]) if ((aoType == 2) or (aoType == 3)): spEpochs.append(i) if ((aoType == 8) or (aoType == 9)): aoEpochs.append(i) i += 1 if (numSpeck == None): numSpeck = len(spEpochs) if (numAO == None): numAO = len(aoEpochs) # For each star, count up the number of speckle and AO epochs it is # detected in. names = s.getArray('name') velCnt = s.getArray('velCnt') numStars = len(names) numEpochs = len(s.stars[0].years) print('Initial: Nstars = %4d Nepochs = %2d' % (numStars, numEpochs)) print('Number of Epochs of Type:') print(' Speckle = %d' % len(spEpochs)) print(' AO = %d' % len(aoEpochs)) aoCnt = np.zeros(numStars) spCnt = np.zeros(numStars) for e in range(numEpochs): pos = s.getArrayFromEpoch(e, 'x') idx = (np.where(pos > -1000))[0] if (e in aoEpochs): aoCnt[idx] += 1 if (e in spEpochs): spCnt[idx] += 1 # Now lets write the output _out = open(outputLabel, 'w') _out.write('%-10s %5s ' % ('#Name', 'K')) _out.write('%7s %7s %7s %7s ' % ('x', 'y', 'xerr', 'yerr')) _out.write('%8s %8s %8s %8s ' % ('vx', 'vy', 'vxerr', 'vyerr')) _out.write('%8s %4s %7s\n' % ('t0', 'use?', 'r2d')) _out.write('%-10s %5s ' % ('#()', '(mag)')) _out.write('%7s %7s %7s %7s ' % \ ('(asec)', '(asec)', '(asec)', '(asec)')) _out.write('%8s %8s %8s %8s ' % \ ('(mas/yr)', '(mas/yr)', '(mas/yr)', '(mas/yr)')) _out.write('%8s %4s %7s\n' % ('(year)', '()', '(asec)')) spNumStars = 0 aoNumStars = 0 use = '1' for i in range(len(labels.name)): # Find this star in our align output try: foo = names.index(labels.name[i]) if (labels.useToAlign[i] == 0): # Preserve any pre-existing use?=0 stars use = '0' if (spCnt[foo] >= numSpeck): print('%-13s is in all speckle epochs, but use=0' % \ names[foo]) else: if (spCnt[foo] >= numSpeck): use = '2' spNumStars += 1 if (aoCnt[foo] >= numAO): aoNumStars += 1 if (use == '2'): # Speckle and AO use += ',8' else: # AO only use = '8' except ValueError: # Don't change anything if we didn't find it. # Reformat to string for ease of use use = str(labels.useToAlign[i]) _out.write('%-10s %5.1f ' % (labels.name[i], labels.mag[i])) _out.write('%7.3f %7.3f ' % (labels.x[i], labels.y[i])) _out.write('%7.3f %7.3f ' % (labels.xerr[i], labels.yerr[i])) _out.write('%8.3f %8.3f ' % (labels.vx[i], labels.vy[i])) _out.write('%8.3f %8.3f ' % (labels.vxerr[i], labels.vyerr[i])) _out.write('%8.3f %-4s %7.3f\n' % \ (labels.t0[i], use, labels.r[i])) _out.close() print('Final: Nstars Speckle = %4d AO = %4d' % \ (spNumStars, aoNumStars))
def makeNewRefList(alignRoot, refList, starPrefix='ep0'): print 'Making new reference list', refList s = starset.StarSet(alignRoot) # Get the zeropoint offset to convert to magRef = s.getArrayFromEpoch(0, 'mag') magLis = s.getArrayFromEpoch(1, 'mag') idx = np.where((magRef != 0) & (magLis != 0))[0] # Only use the first 10 stars if len(idx) > 10: idx = idx[0:10] zp = (magRef[idx] - magLis[idx]).mean() print 'Zeropoint for %s is %.2f' % (starPrefix, zp) _out = open(refList, 'w') for star in s.stars: inRef = False inLis = False if star.e[0].x > -999: inRef = True if star.e[1].x > -999: inLis = True if inRef and inLis: name = star.e[0].name # Rename new stars from the mosaiced images. # Don't rename reference list sources, so we can reject # them later on. if name.startswith('star') and starPrefix != None: name = star.e[1].name.replace('star', starPrefix) # get errors and combine them # centroid, distortion, and residual distortion xe0 = star.e[0].xpixerr_p ye0 = star.e[0].ypixerr_p # centroid, distortion, and residual distortion xe1 = star.e[1].xpixerr_p ye1 = star.e[1].ypixerr_p # align error xea = star.e[1].xpixerr_a yea = star.e[1].ypixerr_a # add the alignment error in quadrature to the frame's other errors xe1_tot = np.hypot(xe1, xea) ye1_tot = np.hypot(ye1, yea) m = star.e[1].mag + zp # get original and aligned positions, then take weighted ave # weight by each field's errors (which contain centroid, # distortion, and residual distortion errors already) x0 = star.e[0].xpix y0 = star.e[0].ypix x1 = star.e[1].xpix y1 = star.e[1].ypix xwt0 = 1. / xe0**2 ywt0 = 1. / ye0**2 xwt1 = 1. / xe1_tot**2 ywt1 = 1. / ye1_tot**2 x = statsWeighted.mean_wgt(np.array([x0,x1]), np.array([xwt0,xwt1])) y = statsWeighted.mean_wgt(np.array([y0,y1]), np.array([ywt0,ywt1])) # For the next reference list's new positional error, we'll # take the average error of the ref and lis errors xerr = (xe0 + xe1_tot) / 2.0 yerr = (ye0 + ye1_tot) / 2.0 else: if inRef: name = star.e[0].name x = star.e[0].xpix y = star.e[0].ypix xe = star.e[0].xpixerr_p ye = star.e[0].ypixerr_p m = star.e[0].mag # just maintain the frame's (centroid+distortion+residual) # errors xerr = xe yerr = ye if inLis: name = star.e[1].name # Rename new stars from the narrow camera stuff. # Don't rename wide camera sources, so we can reject # them later on. if name.startswith('star') and starPrefix != None: name = name.replace('star', starPrefix) x = star.e[1].xpix y = star.e[1].ypix xe = star.e[1].xpixerr_p ye = star.e[1].ypixerr_p xea = star.e[1].xpixerr_a yea = star.e[1].ypixerr_a m = star.e[1].mag + zp # just maintain the frame's (centroid+distortion+residual) # errors. xerr = xe yerr = ye date = star.years[0] _out.write('%-13s %6.3f %9.4f %11.5f %11.5f %8.5f %8.5f 1 1 1 1\n' % (name, m, date, x, y, xerr, yerr)) _out.close()
def plotLabelAndAlign(alignRoot, polyRoot, magCut=25, labelFile='label.dat', showStars=True): label = starTables.Labels(labelFile) label.take(np.where(label.mag < magCut)[0]) t = 2005.580 x_lab = label.x + label.vx * (t - label.t0) / 10**3 y_lab = label.y + label.vy * (t - label.t0) / 10**3 n_lab = label.ourName use = label.useToAlign # Now read in the align stuff s = starset.StarSet(alignRoot) s.loadPolyfit(polyRoot, accel=0) mag = s.getArray('mag') idx = np.where(mag < magCut)[0] s.stars = [s.stars[ii] for ii in idx] n_aln = np.array(s.getArray('name')) mag = s.getArray('mag') x0 = s.getArray('fitXv.p') * -1.0 y0 = s.getArray('fitYv.p') x0err = s.getArray('fitXv.perr') y0err = s.getArray('fitYv.perr') vx = s.getArray('fitXv.v') * -1.0 vy = s.getArray('fitYv.v') vxerr = s.getArray('fitXv.verr') vyerr = s.getArray('fitYv.verr') t0x = s.getArray('fitXv.t0') t0y = s.getArray('fitYv.t0') r = np.hypot(x0, y0) x_aln = x0 + vx * (t - t0x) y_aln = y0 + vy * (t - t0y) # Fix x0err, y0err to some minimum value idx = np.where(x0err < 0.0001)[0] x0err[idx] = 0.0001 idx = np.where(y0err < 0.0001)[0] y0err[idx] = 0.0001 # First lets update the 16 sources since they are used # to align label.dat to the reference epoch (crude I know) names16 = [ 'irs16C', 'irs16NW', 'irs16CC', 'irs16NE', 'irs16SW', 'irs16SW-E', 'irs33N', 'irs33E' ] for nn in range(len(names16)): idx = np.where(n_aln == names16[nn])[0] for rr in idx: print '%-11s %4.1f %6.3f %6.3f %7.4f %7.4f %8.3f %8.3f %7.3f %7.3f %8.3f 1 %5.3f' % \ (n_aln[rr], mag[rr], x0[rr], y0[rr], x0err[rr], y0err[rr], vx[rr]*10**3, vy[rr]*10**3, vxerr[rr]*10**3, vyerr[rr]*10**3, t0x[rr], r[rr]) # Image imageFile = '/u/ghezgroup/data/gc/' imageFile += '06maylgs1/combo/mag06maylgs1_dp_msc_kp.fits' im = pyfits.getdata(imageFile) imgsize = (im.shape)[0] # pixel position (0,0) is at upper left xpix = np.arange(0, im.shape[0], dtype=float) ypix = np.arange(0, im.shape[1], dtype=float) sgra = [1422.6, 1543.8] scale_jpg = 0.00994 xim = (xpix - sgra[0]) * scale_jpg * -1.0 yim = (ypix - sgra[1]) * scale_jpg # Lets also make some coordinates for compass rose and scale bar xrose = np.array([-15.5, -15.5]) yrose = np.array([15.5, 15.5]) xroseLen = np.array([20.0, 0.0]) yroseLen = np.array([0.0, 20.0]) py.clf() py.close(1) py.close(2) def drawImage(xlo, xhi, ylo, yhi): py.figure(2, figsize=(9, 9)) py.grid(True) py.subplots_adjust(left=0.05, right=0.95, bottom=0.05, top=0.95) py.imshow(np.log10(im), extent=[xim[0], xim[-1], yim[0], yim[-1]], aspect='equal', vmin=2.0, vmax=4.0, cmap=py.cm.gray) py.xlabel('X Offset from Sgr A* (arcsec)') py.ylabel('Y Offset from Sgr A* (arcsec)') py.title('UCLA/Keck Galactic Center Group', fontsize=20, fontweight='bold') thePlot = py.gca() # Plot label.dat points py.plot(x_lab, y_lab, 'rs') for ii in range(len(x_lab)): py.text(x_lab[ii], y_lab[ii], n_lab[ii], color='red', fontsize=10) # Plot align points py.plot(x_aln, y_aln, 'bo') for ii in range(len(x_aln)): py.text(x_aln[ii], y_aln[ii], n_aln[ii], color='blue', fontsize=10) py.axis([xlo, xhi, ylo, yhi]) # We can do some matching here to help us out. drawImage(15, -15, -15, 15) if showStars: fmt = '%-11s %4.1f %9.5f %9.5f %8.5f %8.5f %8.3f %8.3f %7.3f %7.3f %8.3f %1d %5.3f\n' gcutil.rmall(['label_updated.dat']) out = open('label_updated.dat', 'w') out.write( '#Name K x y xerr yerr vx vy vxerr vyerr t0 use? r2d\n' ) out.write( '#() (mag) (asec) (asec) (asec) (asec) (mas/yr) (mas/yr) (mas/yr) (mas/yr) (year) () (asec)\n' ) foo = raw_input('Continue?') for ss in range(len(x_lab)): update = 0 idx = np.where(n_aln == n_lab[ss])[0] # The rest of the code allows us to find stars that were not matched # between the old label and new absolute alignment. # This will write out the new info from absolute alignment to a new # label_updated.dat file for just those stars that weren't matched properly, # but still need to run updateLabelInfoWithAbsRefs() to update the info # for stars that were matched. if len(idx) == 0: dr = np.hypot(x_aln - x_lab[ss], y_aln - y_lab[ss]) rdx = np.where(dr < 0.2)[0] if len(rdx) > 0: xlo = x_lab[ss] + 0.2 xhi = x_lab[ss] - 0.2 ylo = y_lab[ss] - 0.2 yhi = y_lab[ss] + 0.2 py.axis([xlo, xhi, ylo, yhi]) print 'Did not find a match for %s (K=%4.1f x=%7.3f y = %7.3f):' % \ (n_lab[ss], label.mag[ss], x_lab[ss], y_lab[ss]) for rr in rdx: print fmt % \ (n_aln[rr], mag[rr], x0[rr], y0[rr], x0err[rr], y0err[rr], vx[rr]*10**3, vy[rr]*10**3, vxerr[rr]*10**3, vyerr[rr]*10**3, t0x[rr], use[ss], r[rr]) # if the starname in align has the same ending as the name in # label.dat, it's likely the same star (e.g. '1S9-87' and 'S9-87'; # Note that this is the naming used in mosaicked star list analysis) if n_aln[rr].endswith(n_lab[ss]): # do a check that these stars have similar magnitudes if np.abs(label.mag[ss] - mag[rr]) <= 0.5: update = 1 # replace the whole line in label_updated.dat out.write(fmt % \ (n_lab[ss], mag[rr], x0[rr], y0[rr], x0err[rr], y0err[rr], vx[rr]*10**3, vy[rr]*10**3, vxerr[rr]*10**3, vyerr[rr]*10**3, t0x[rr], use[ss], r[rr])) continue else: foo = raw_input( 'Similar names, but magnitudes are off. Check star %s manually and decide whether or not to replace it in label_updated.dat when this program completes. Hit enter to continue.' % n_aln[rr]) # Or the star just wasn't matched with any star in the old label.dat file # and was given an arbitrary name elif (('star' in n_aln[rr]) | ('ep' in n_aln[rr])): print 'Manually check and update this star if needed:' print 'Name in label: %s' % n_lab[ss] print 'Name in new alignment: %s' % n_aln[rr] if len(rdx) > 1: print 'CAUTION: There are other nearby stars, including:' for ii in range(len(rdx)): print n_aln[rdx[ii]] update = raw_input( 'Update with %s velocity? (enter 1 for yes; 0 for no) ' % n_aln[rr]) update = int(update) if update == 1: out.write(fmt % \ (n_lab[ss], mag[rr], x0[rr], y0[rr], x0err[rr], y0err[rr], vx[rr]*10**3, vy[rr]*10**3, vxerr[rr]*10**3, vyerr[rr]*10**3, t0x[rr], use[ss], r[rr])) # check magnitude offset #if np.abs(label.mag[ss] - mag[rr]) <= 0.5: # update = 1 # # replace the whole line in label_updated.dat # out.write(fmt % \ # (n_lab[ss], mag[rr], x0[rr], y0[rr], x0err[rr], # y0err[rr], vx[rr]*10**3, vy[rr]*10**3, # vxerr[rr]*10**3, vyerr[rr]*10**3, t0x[rr], 1, r[rr])) if update == 0: # just re-write what was in label.dat, and later run # updateLabelInfoWithAbsRefs() to update matched stars with the new # absolute alignment out.write(fmt % \ (label.ourName[ss], label.mag[ss], label.x[ss], label.y[ss], label.xerr[ss], label.yerr[ss], label.vx[ss], label.vy[ss], label.vxerr[ss], label.vyerr[ss], label.t0[ss], use[ss], label.r[ss])) out.close()
def histogram(root='./', align='align/align_d_rms_t', poly='polyfit_d_points/fit', accel=False, youngOnly=False, trimMaxEpochs=True): s = starset.StarSet(root + align) s.loadPolyfit(root + poly, arcsec=1, accel=accel) if (youngOnly): s.onlyYoungDisk() if (accel): chi2Xred = s.getArray('fitXa.chi2red') chi2Yred = s.getArray('fitYa.chi2red') chi2X = s.getArray('fitXa.chi2') chi2Y = s.getArray('fitYa.chi2') dof = s.getArray('fitXa.dof') else: chi2Xred = s.getArray('fitXv.chi2red') chi2Yred = s.getArray('fitYv.chi2red') chi2X = s.getArray('fitXv.chi2') chi2Y = s.getArray('fitYv.chi2') dof = s.getArray('fitXv.dof') cnt = s.getArray('velCnt') if trimMaxEpochs: idx = np.where(cnt == cnt.max())[0] chi2Xred = chi2Xred[idx] chi2Yred = chi2Yred[idx] chi2X = chi2X[idx] chi2Y = chi2Y[idx] dof = dof[idx] cnt = cnt[idx] # ========== # First histograms on the chi2 (not reduced) # ========== # Plot the unreduced distribution binSize = np.median(chi2X) / 10.0 binsIn = np.arange(0, dof.max() * 100, binSize) binScale = 100.0 binsInModel = np.arange(0, dof.max() * 100, binSize / binScale) chi2model = np.zeros(len(binsInModel), dtype=float) # Make a model distribution using the appropriate degrees of # freedom for all the stars. maxEpochCnt = cnt.max() minEpochCnt = cnt.min() for ii in range(minEpochCnt, maxEpochCnt + 1): idx = np.where(cnt == ii)[0] if len(idx) > 0: chi2 = scipy.stats.chi2(dof[idx[0]]) # Get PDF, and then convert to histogram with the # Same prob/bin as our data histogram tmp = chi2.pdf(binsInModel) * len(idx) * binSize # Add to our model chi2model += tmp # Plot up the results py.clf() # X py.subplot(2, 1, 1) (n, bins, p) = py.hist(chi2X, bins=binsIn, alpha=0.6) p1 = py.plot(binsInModel, chi2model) py.xlim(0, dof.max() * 5) py.ylabel('Number of Stars') py.xlabel('X Velocity Fit Chi^2') py.title('%d stars in %d-%d Epochs' % (len(chi2Xred), cnt.min(), cnt.max())) # Y py.subplot(2, 1, 2) (n, bins, p) = py.hist(chi2Y, bins=binsIn, alpha=0.6) p1 = py.plot(binsInModel, chi2model) py.xlim(0, dof.max() * 5) py.ylabel('Number of Stars') py.xlabel('Y Velocity Fit Chi^2') if trimMaxEpochs: outputFile = root + 'plots/poly_chi2_hist_max_dof.png' else: outputFile = root + 'plots/poly_chi2_hist_all_dof.png' py.savefig(outputFile) # ========== # Now histograms on the reduced-chi2 # ========== # Plot the reduced distribution binSize = np.median(chi2Xred) / 10.0 binsIn = np.arange(0, 100, binSize) binScale = 100.0 binsInModel = np.arange(0, 100, binSize / binScale) chi2model = np.zeros(len(binsInModel), dtype=float) # Make a model distribution using the appropriate degrees of # freedom for all the stars. maxEpochCnt = cnt.max() minEpochCnt = cnt.min() for ii in range(minEpochCnt, maxEpochCnt + 1): idx = np.where(cnt == ii)[0] if len(idx) > 0: degreesOfFreedom = dof[idx[0]] chi2 = scipy.stats.chi2(degreesOfFreedom) # Get PDF, and then convert to histogram with the # Same prob/bin as our data histogram tmp = chi2.pdf(binsInModel * degreesOfFreedom) tmp *= len(idx) * binScale / tmp.sum() # Add to our model chi2model += tmp # Plot up the results py.clf() # X py.subplot(2, 1, 1) (n, bins, p) = py.hist(chi2Xred, bins=binsIn, alpha=0.6) p1 = py.plot(binsInModel, chi2model) py.xlim(0, 5) py.ylabel('Number of Stars') py.xlabel('X Velocity Fit Reduced Chi^2') py.title('%d stars in %d-%d Epochs' % (len(chi2Xred), cnt.min(), cnt.max())) # Y py.subplot(2, 1, 2) (n, bins, p) = py.hist(chi2Yred, bins=binsIn, alpha=0.6) p1 = py.plot(binsInModel, chi2model) py.xlim(0, 5) py.ylabel('Number of Stars') py.xlabel('Y Velocity Fit Reduced Chi^2') if trimMaxEpochs: outputFile = root + 'plots/poly_chi2red_hist_max_dof.png' else: outputFile = root + 'plots/poly_chi2red_hist_all_dof.png' py.savefig(outputFile)
def AlignModel(t0, beta, tau, i0, target, align, source_m=True, ang=0.0, mL=1.0, dL=4000.0, dS=8000.0, save_fig=False, outdir='./'): ''' Compares a PSPL model based on input assumptions against aligned data. Args: t0 - float: Time of peak photometric signal in days (t=0 on New Year's of year 0, UTC). beta - float: Minimum angular distance between source and lens in mas. tau - float: Einstein crossing time in days. i0 - float: Base photometric magnitude. target - str: Name of the target. align - str: Path to the alignment directory. source_m - bool: Determine if either the source is the moving object (True) or the lens (False). ang - float: Angle (degrees) at which the moving object travels w.r.t. the ecliptic. mL - float: Mass of the lens in solar masses. dL - float: Distance to the lens in parsecs. dS - float: Distance to the source in parsecs. save_fig - bool: To save or not to save the figure. outdir - str: Path to save figure. Folder is created in outdir. ''' test, modeled = assume(t0, beta, tau, i0, ang, mL, dL, dS, source_m) if save_fig == True: os.chdir(outdir) test_dir = (outdir + test) print('Saving in ' + test_dir) if os.path.exists(test_dir) == False: os.mkdir(test_dir) # get the aligned data s = starset.StarSet(align + 'align/align_t') s.loadPolyfit(align + 'polyfit_d/fit', accel=0, arcsec=0) names = s.getArray('name') ss = names.index(target) star = s.stars[ss] pointsTab = Table.read(align + 'points_d/' + target + '.points', format='ascii') at = pointsTab[pointsTab.colnames[0]] ax = pointsTab[pointsTab.colnames[1]] ay = pointsTab[pointsTab.colnames[2]] axerr = pointsTab[pointsTab.colnames[3]] ayerr = pointsTab[pointsTab.colnames[4]] fitx = star.fitXv fity = star.fitYv mt = np.arange(t0 - 1500, t0 + 1500, 1) mdt = mt - modeled.t0 adt = at - (modeled.t0 / 365.25) fdt = at - fitx.t0 thE = modeled.thetaE_amp mshift = modeled.get_centroid_shift(mt) fitLineX = fitx.p + (fitx.v * fdt) fitSigX = np.sqrt(fitx.perr**2 + (fdt * fitx.verr)**2) fitLineY = fity.p + (fity.v * fdt) fitSigY = np.sqrt(fity.perr**2 + (fdt * fity.verr)**2) adt *= 365.25 axf = (ax - fitLineX) ayf = (ay - fitLineY) ## plot everything scaled in Einstein units # x data alignment = align[-27:-1] fig = py.figure(figsize=(20, 10)) xpl = py.subplot(211) py.plot(mdt / modeled.tE, mshift[:, 0] / thE, 'k-') py.errorbar(adt / modeled.tE, axf * 9.95 / thE, yerr=axerr * 9.95 / thE, fmt='ro') py.legend(['model (tE = %.2f days)' % (modeled.tE), alignment], loc=4) py.plot(adt / modeled.tE, fitSigX * 9.95 / thE, 'b--') py.plot(adt / modeled.tE, -fitSigX * 9.95 / thE, 'b--') xpl.set_ylabel(r'dX / $\theta_E$') py.title(test[1:-1] + r' - $\theta_E =$ %.2f [mas]' % thE) # y data ypl = py.subplot(212, sharex=xpl) py.subplots_adjust(hspace=0) py.plot(mdt / modeled.tE, mshift[:, 1] / thE, 'k-') py.plot(adt / modeled.tE, fitSigY * 9.95 / thE, 'b--') py.plot(adt / modeled.tE, -fitSigY * 9.95 / thE, 'b--') py.errorbar(adt / modeled.tE, ayf * 9.95 / thE, yerr=ayerr * 9.95 / thE, fmt='ro') ypl.set_ylabel(r'dY / $\theta_E$') ypl.set_xlabel('(t - t0) / tE') if save_fig == True: py.savefig(test_dir + 'shift_v_t.png') py.show() ## zoomed-in plot with residuals # approximate residual to integer model times madt = np.round(adt) xr = [] yr = [] for i in range(len(madt)): idx = np.where(mdt == madt[i])[0] xr.append(axf[i] * 9.95 - mshift[idx, 0]) yr.append(ayf[i] * 9.95 - mshift[idx, 1]) xr = np.array(xr) yr = np.array(yr) fig2, (xplz, xres, yplz, yres) = py.subplots(4, 1, figsize=(15, 15), gridspec_kw={'height_ratios': [3, 1, 3, 1]}, sharex=True) fig2.subplots_adjust(hspace=0) xplz.plot(mdt / modeled.tE, mshift[:, 0] / thE, 'k-') xplz.errorbar(adt / modeled.tE, axf * 9.95 / thE, yerr=axerr * 9.95 / thE, fmt='ro') xplz.legend(['model (tE = %.2f days)' % (modeled.tE), alignment], loc=4) xplz.plot(adt / modeled.tE, fitSigX * 9.95 / thE, 'b--') xplz.plot(adt / modeled.tE, -fitSigX * 9.95 / thE, 'b--') xplz.set_ylabel(r'dX / $\theta_E$') xplz.set_title(test[1:-1] + r' - $\theta_E =$ %.2f [mas]' % thE) xres.errorbar(adt / modeled.tE, xr / thE, yerr=axerr * 9.95 / thE, fmt='ro') xres.axhline(color='k') xres.set_ylabel('dX res') yplz.plot(mdt / modeled.tE, mshift[:, 1] / thE, 'k-') yplz.plot(adt / modeled.tE, fitSigY * 9.95 / thE, 'b--') yplz.plot(adt / modeled.tE, -fitSigY * 9.95 / thE, 'b--') yplz.errorbar(adt / modeled.tE, ayf * 9.95 / thE, yerr=ayerr * 9.95 / thE, fmt='ro') yplz.set_xlim( [adt[0] / modeled.tE - 2, adt[len(adt) - 1] / modeled.tE + 2]) yplz.set_ylabel(r'dY / $\theta_E$') yres.errorbar(adt / modeled.tE, yr / thE, yerr=ayerr * 9.95 / thE, fmt='ro') yres.axhline(color='k') yres.set_ylabel('dY res') yres.set_xlabel('(t - t0) / tE') if save_fig == True: py.savefig(test_dir + 'shift_v_t_zoom.png') py.show()
def medianError(root='./', align='align/align_d_rms_t', poly='polyfit_d_points/fit', points='points_d/', youngOnly=False, adjustPoints=False): """ Determine the median error in the Y direction for all stars during all epochs. """ # Load up our starlist s = starset.StarSet(root + align) if (youngOnly): s.onlyYoungDisk() xerrAll = np.arange(0, float) yerrAll = np.arange(0, float) # We also want to get median errors for varioius # magnitude bins. err9_10 = np.arange(0, float) err10_11 = np.arange(0, float) err11_12 = np.arange(0, float) err12_13 = np.arange(0, float) err13_14 = np.arange(0, float) err14_15 = np.arange(0, float) for star in s.stars: pointsFile = root + points + star.name + '.points' pointsTab = asciidata.open(pointsFile) # Observed Data t = pointsTab[0].tonumpy() x = pointsTab[1].tonumpy() y = pointsTab[2].tonumpy() xerr = pointsTab[3].tonumpy() yerr = pointsTab[4].tonumpy() xerrAll = np.concatenate((xerrAll, xerr)) yerrAll = np.concatenate((yerrAll, yerr)) if (star.mag >= 9 and star.mag < 10): err9_10 = np.concatenate((err9_10, yerr)) if (star.mag >= 10 and star.mag < 11): err10_11 = np.concatenate((err10_11, yerr)) if (star.mag >= 11 and star.mag < 12): err11_12 = np.concatenate((err11_12, yerr)) if (star.mag >= 12 and star.mag < 13): err12_13 = np.concatenate((err12_13, yerr)) if (star.mag >= 13 and star.mag < 14): err13_14 = np.concatenate((err13_14, yerr)) if (star.mag >= 14 and star.mag < 15): err14_15 = np.concatenate((err14_15, yerr)) print 'Median X err: %7.4f (pix)' % np.median(xerrAll) print 'Median Y err: %7.4f (pix)' % np.median(yerrAll) mag = arange(9.5, 15, 1.0) medianMag = array([ np.median(err9_10), np.median(err10_11), np.median(err11_12), np.median(err12_13), np.median(err13_14), np.median(err14_15) ]) py.clf() py.plot(mag, medianMag, 'k^') py.xlabel('Magnitude') py.ylabel('Median Error (pix)') # Stars in K=11-12 bin seem to be well fit. So lets determine # the global scale parameter by adjusting the next lowest bin # up to that level sysErr = np.sqrt(medianMag[2]**2 - medianMag[1]**2) / 1.5 #sysErr = 0.03 print 'Systematic Error to be quad summed to Y: ', sysErr # --- The sysErr will be added in quadrature to everything. # --- Adjustment will only be made in the Y direction. if (adjustPoints): # Points adjustment must happen on ALL stars s = starset.StarSet(root + align) newPoints = points[:-1] + '_err/' print 'Adjusted points saved to ', newPoints for star in s.stars: oldPointsFile = root + points + star.name + '.points' newPointsFile = root + newPoints + star.name + '.points' pointsTab = asciidata.open(oldPointsFile) date = pointsTab[0].tonumpy() oldErrX = pointsTab[3].tonumpy() oldErrY = pointsTab[4].tonumpy() #newErrX = oldErrX newErrX = np.sqrt(oldErrX**2 + sysErr**2) newErrY = np.sqrt(oldErrY**2 + sysErr**2) for row in range(len(oldErrX)): pointsTab[3][row] = newErrX[row] pointsTab[4][row] = newErrY[row] # Temporarily delete AO epochs #pointsTab.delete(len(oldErrX) - 2) #pointsTab.delete(len(oldErrX) - 5) # Temporarily scale AO epochs #ao1 = len(oldErrX) - 2 #pointsTab[3][ao1] = sqrt(oldErrX[ao1]**2 + 0.08**2) #pointsTab[4][ao1] = sqrt(oldErrY[ao1]**2 + 0.08**2) #ao2 = len(oldErrX) - 5 #pointsTab[3][ao2] = sqrt(oldErrX[ao2]**2 + 0.08**2) #pointsTab[4][ao2] = sqrt(oldErrY[ao2]**2 + 0.08**2) pointsTab.writeto(newPointsFile)
def plot_vector_diff(undersample): """ Make a vector plot of the differences between the input positions and the output positions after running starfinder. """ # Dimensions of new grid npsf_side = get_npsf_side(undersample) suffix = '%d_%d' % (npsf_side, npsf_side) s = starset.StarSet('grid_' + suffix + '/align_' + suffix) cnt = s.getArray('velCnt') mag = s.getArray('mag') idx = np.where((cnt == 2) & (mag < 15))[0] print 'Using {0} stars out of {1}'.format(len(idx), len(cnt)) newStars = [s.stars[ii] for ii in idx] s.stars = newStars x0 = s.getArrayFromEpoch(0, 'xorig') y0 = s.getArrayFromEpoch(0, 'yorig') x1 = s.getArrayFromEpoch(1, 'xorig') y1 = s.getArrayFromEpoch(1, 'yorig') dx = x1 - x0 dy = y1 - y0 dr = np.hypot(dx, dy) # Boundaries t = atpy.Table('svpar_' + suffix + '.txt', type='ascii') lx = t.col1 ux = t.col2 ly = t.col3 uy = t.col4 xedges = np.unique(np.append(lx, ux)) yedges = np.unique(np.append(ly, uy)) py.clf() q = py.quiver(x0, y0, dx, dy, scale=0.2) py.xlim(0, 1200) py.ylim(0, 1200) py.quiverkey(q, 0.5, 0.97, 0.02, '0.02 pixel (0.2 mas)', color='red', coordinates='axes') for xx in xedges: py.axvline(xx, linestyle='--') for yy in yedges: py.axhline(yy, linestyle='--') py.savefig('plots/vec_diff_' + suffix + '.png') xmean = statsIter.mean(dx, hsigma=5, lsigma=5, iter=5) ymean = statsIter.mean(dy, hsigma=5, lsigma=5, iter=5) rmean = statsIter.mean(dr, hsigma=5, lsigma=5, iter=5) xstd = statsIter.std(dx, hsigma=5, lsigma=5, iter=5) ystd = statsIter.std(dy, hsigma=5, lsigma=5, iter=5) rstd = statsIter.std(dr, hsigma=5, lsigma=5, iter=5) print('Mean Delta-X: {0:9.5f} +/- {1:9.5f} pixels'.format(xmean, xstd)) print('Mean Delta-Y: {0:9.5f} +/- {1:9.5f} pixels'.format(ymean, ystd)) print('Mean Delta-R: {0:9.5f} +/- {1:9.5f} pixels'.format(rmean, rstd)) f_name = 'diff_stats_' + suffix + '.txt' f_stat = open(f_name, 'w') hdr = '#{0:>5s} {1:>10s} {2:>10s} {3:>10s} {4:>10s} {5:>10s} {6:>10s}\n' fmt = '{0:6d} {1:10.5f} {2:10.5f} {3:10.5f} {4:10.5f} {5:10.5f} {6:10.5f}\n' f_stat.write( hdr.format('Npsf', 'Xmean', 'Ymean', 'Rmean', 'Xstd', 'Ystd', 'Rstd')) f_stat.write(fmt.format(npsf_side, xmean, ymean, rmean, xstd, ystd, rstd)) f_stat.close() return f_name
def PhotoModel(t0, beta, tau, i0, stars, align, source_m=True, ang=0.0, mL=1.0, dL=4000.0, dS=8000.0, save_fig=False, outdir='./'): ''' Creates a PSPL model based on input assumptions against aligned data. Args: t0 - float: Time of peak photometric signal in days (t=0 on New Year's of year 0, UTC). beta - float: Minimum angular distance between source and lens in mas. tau - float: Einstein crossing time in days. i0 - float: Base photometric magnitude. stars - str array: Array of stars. align - str: Path to the alignment directory. source_m - bool: Determine if either the source is the moving object (True) or the lens (False). ang - float: Angle (degrees) at which the moving object travels w.r.t. the ecliptic. mL - float: Mass of the lens in solar masses. dL - float: Distance to the lens in parsecs. dS - float: Distance to the source in parsecs. save_fig - bool: To save or not to save the figure. outdir - str: Path to save figure. Folder is created in outdir. ''' test, modeled = assume(t0, beta, tau, i0, ang, mL, dL, dS, source_m) if save_fig == True: os.chdir(outdir) test_dir = (outdir + test) print('Saving in ' + test_dir) if os.path.exists(test_dir) == False: os.mkdir(test_dir) # get the model and aligned data s = starset.StarSet(align + 'align/align_t') s.loadPolyfit(align + 'polyfit_d/fit', accel=0, arcsec=0) # x = s.getArrayFromAllEpochs('xpix') # y = s.getArrayFromAllEpochs('ypix') # xe_p = s.getArrayFromAllEpochs('xpixerr_p') # ye_p = s.getArrayFromAllEpochs('ypixerr_p') N_epochs = len(s.years) mags = np.zeros([N_epochs, 3]) mean_mag = np.zeros([3, 1]) for i in range(len(stars)): photTab = Table.read(align + 'points_d/' + stars[i] + '.phot', format='ascii') mags[:, i] = photTab[photTab.colnames[6]] if i == 0: m0 = photTab[photTab.colnames[6]] mean_mag[i] = np.mean(mags[:, i]) mags[:, i] -= mean_mag[i] at = photTab[photTab.colnames[0]] mt = np.arange(t0 - 1500, t0 + 1500, 1) mdt = mt - modeled.t0 adt = at - (modeled.t0 / 365.25) adt *= 365.25 #get OGLE data ogle = Table.read( '/g/lu/microlens/cross_epoch/OB150211/OGLE-2015-BLG-0211.dat', format='ascii') ot = (ogle['col1'] - 1721057.5) / 365.25 om = ogle['col2'] omr = ogle['col3'] # get the modeled photometry photo = modeled.get_photometry(at * 365.25) pdb.set_trace() fig1 = py.figure(figsize=(8, 8)) py.errorbar(ot, om, yerr=omr, fmt='o') py.plot(at, photo, 'ko', at, m0 + 7.83, 'ro') py.gca().invert_yaxis() py.ylabel('mag') py.legend(['model', 'uncalibrated data + 7.83', 'OGLE O-IV optimized']) py.tight_layout() if save_fig: py.savefig(test_dir + 'model_phot.png') py.show() fig2 = py.figure(figsize=(8, 8)) py.plot(at, mags[:, 0], 'ko', at, mags[:, 1], 'o', at, mags[:, 2], 'o') py.legend([stars[0], stars[1], stars[2]]) py.ylabel(r'$\Delta$mag') py.tight_layout() if save_fig: py.savefig(test_dir + 'del_phot.png') py.show() return photo
def cdf(root='./', align='align/align_d_rms_t', poly='polyfit_d_points/fit', accel=False, youngOnly=False, trimMaxEpochs=True): s = starset.StarSet(root + align) s.loadPolyfit(root + poly, arcsec=1, accel=accel) if (youngOnly): s.onlyYoungDisk() if (accel): chi2Xred = s.getArray('fitXa.chi2red') chi2Yred = s.getArray('fitYa.chi2red') chi2X = s.getArray('fitXa.chi2') chi2Y = s.getArray('fitYa.chi2') dof = s.getArray('fitXa.dof') else: chi2Xred = s.getArray('fitXv.chi2red') chi2Yred = s.getArray('fitYv.chi2red') chi2X = s.getArray('fitXv.chi2') chi2Y = s.getArray('fitYv.chi2') dof = s.getArray('fitXv.dof') cnt = s.getArray('velCnt') if trimMaxEpochs: idx = np.where(cnt == cnt.max())[0] chi2Xred = chi2Xred[idx] chi2Yred = chi2Yred[idx] chi2X = chi2X[idx] chi2Y = chi2Y[idx] dof = dof[idx] cnt = cnt[idx] # Make a model distribution using the appropriate degrees of # freedom for all the stars. maxEpochCnt = cnt.max() minEpochCnt = cnt.min() # ========== # First analyze chi^2 (not reduced) # ========== chi2Xsorted = chi2X.copy() chi2Xsorted.sort() chi2Ysorted = chi2Y.copy() chi2Ysorted.sort() cdfObserved = (np.arange(len(chi2X)) + 1.) / len(chi2X) def cdfModel(chi2data): chi2model = np.zeros(len(chi2data), dtype=float) for ii in range(minEpochCnt, maxEpochCnt + 1): idx = np.where(cnt == ii)[0] if len(idx) > 0: degreesOfFreedom = dof[idx[0]] chi2 = scipy.stats.chi2(degreesOfFreedom) tmp = chi2.cdf(chi2data) tmp *= float(len(idx)) / len(chi2data) chi2model += tmp return chi2model chi2modelX = cdfModel(chi2Xsorted) chi2modelY = cdfModel(chi2Ysorted) foox = scipy.stats.kstest(chi2Xsorted, cdfModel) fooy = scipy.stats.kstest(chi2Ysorted, cdfModel) print foox, fooy print 'KS Test - Probability that observations follow expected distribution:' print ' X: D = %.2f P = %e' % (foox[0], foox[1]) print ' Y: D = %.2f P = %e' % (fooy[0], fooy[1]) # Plot up the results py.clf() # X py.subplot(2, 1, 1) py.plot(chi2Xsorted, cdfObserved, 'k-') py.plot(chi2Xsorted, chi2modelX, 'b-') py.xlim(0, dof[0] * 5) py.ylabel('CDF for X Vel. Fit') py.title('%d stars in %d-%d epochs' % (len(chi2Xred), cnt.min(), cnt.max())) # Y py.subplot(2, 1, 2) py.plot(chi2Ysorted, cdfObserved, 'k-') py.plot(chi2Ysorted, chi2modelY, 'b-') py.xlim(0, dof[0] * 5) py.ylabel('CDF for Y Vel. Fit') py.xlabel('Chi^2') py.legend(('Observed', 'Model'), loc='lower right') if trimMaxEpochs: outputFile = root + 'plots/poly_chi2_cdf_max_dof.png' else: outputFile = root + 'plots/poly_chi2_cdf_all_dof.png' py.savefig(outputFile) # ========== # Now analyze reduced chi^2 # ========== chi2Xsorted = chi2Xred.copy() chi2Xsorted.sort() chi2Ysorted = chi2Yred.copy() chi2Ysorted.sort() cdfObserved = (np.arange(len(chi2Xred)) + 1.) / len(chi2Xred) def cdfModel(chi2data): # Here chi2data is a list of reduced chi2 values. chi2model = np.zeros(len(chi2data), dtype=float) for ii in range(minEpochCnt, maxEpochCnt + 1): idx = np.where(cnt == ii)[0] if len(idx) > 0: degreesOfFreedom = dof[idx[0]] chi2 = scipy.stats.chi2(degreesOfFreedom) tmp = chi2.cdf(chi2data * degreesOfFreedom) tmp *= float(len(idx)) / len(chi2data) chi2model += tmp return chi2model chi2modelX = cdfModel(chi2Xsorted) chi2modelY = cdfModel(chi2Ysorted) foox = scipy.stats.kstest(chi2Xsorted, cdfModel) fooy = scipy.stats.kstest(chi2Ysorted, cdfModel) print 'KS Test - Probability that observations follow expected distribution:' print ' X: D = %.2f P = %e' % (foox[0], foox[1]) print ' Y: D = %.2f P = %e' % (fooy[0], fooy[1]) # Plot up the results py.clf() # X py.subplot(2, 1, 1) py.plot(chi2Xsorted, cdfObserved, 'k-') py.plot(chi2Xsorted, chi2modelX, 'b-') py.xlim(0, 5) py.ylabel('CDF for X Vel. Fit') py.title('%d stars in %d-%d epochs' % (len(chi2Xred), cnt.min(), cnt.max())) # Y py.subplot(2, 1, 2) py.plot(chi2Ysorted, cdfObserved, 'k-') py.plot(chi2Ysorted, chi2modelY, 'b-') py.xlim(0, 5) py.ylabel('CDF for Y Vel. Fit') py.xlabel('Reduced Chi^2') py.legend(('Observed', 'Model'), loc='lower right') if trimMaxEpochs: outputFile = root + 'plots/poly_chi2red_cdf_max_dof.png' else: outputFile = root + 'plots/poly_chi2red_cdf_all_dof.png' py.savefig(outputFile)
def plot_3_targs(): #name three objects targNames = ['ob140613', 'ob150211', 'ob150029'] #object alignment directories an_dirs = [ '/g/lu/microlens/cross_epoch/OB140613/a_2018_09_24/prop/', '/g/lu/microlens/cross_epoch/OB150211/a_2018_09_19/prop/', '/g/lu/microlens/cross_epoch/OB150029/a_2018_09_24/prop/' ] align_dirs = ['align/align_t', 'align/align_t', 'align/align_t'] points_dirs = ['points_a/', 'points_d/', 'points_d/'] poly_dirs = ['polyfit_a/fit', 'polyfit_d/fit', 'polyfit_d/fit'] xlim = [1.2, 2.0, 1.5] ylim = [1.0, 7.0, 1.5] #Output file #filename = '/Users/jlu/doc/proposals/keck/uc/19A/plot_3_targs.png' filename = '/Users/jlu/plot_3_targs.png' #figsize = (15, 4.5) figsize = (10, 4.5) ps = 9.92 py.close(1) py.figure(1, figsize=figsize) Ntarg = len(targNames) - 1 for i in range(Ntarg): rootDir = an_dirs[i] starName = targNames[i] align = align_dirs[i] poly = poly_dirs[i] point = points_dirs[i] s = starset.StarSet(rootDir + align) s.loadPolyfit(rootDir + poly, accel=0, arcsec=0) names = s.getArray('name') mag = s.getArray('mag') x = s.getArray('x') y = s.getArray('y') ii = names.index(starName) star = s.stars[ii] pointsTab = Table.read(rootDir + point + starName + '.points', format='ascii') time = pointsTab[pointsTab.colnames[0]] x = pointsTab[pointsTab.colnames[1]] y = pointsTab[pointsTab.colnames[2]] xerr = pointsTab[pointsTab.colnames[3]] yerr = pointsTab[pointsTab.colnames[4]] if i == 0: print('Doing MJD') idx_2015 = np.where(time <= 57387) idx_2016 = np.where((time > 57387) & (time <= 57753)) idx_2017 = np.where((time > 57753) & (time <= 58118)) idx_2018 = np.where((time > 58119) & (time <= 58484)) else: idx_2015 = np.where(time < 2016) idx_2016 = np.where((time >= 2016) & (time < 2017)) idx_2017 = np.where((time >= 2017) & (time < 2018)) idx_2018 = np.where((time >= 2018) & (time < 2019)) fitx = star.fitXv fity = star.fitYv dt = time - fitx.t0 fitLineX = fitx.p + (fitx.v * dt) fitSigX = np.sqrt(fitx.perr**2 + (dt * fitx.verr)**2) fitLineY = fity.p + (fity.v * dt) fitSigY = np.sqrt(fity.perr**2 + (dt * fity.verr)**2) from matplotlib.ticker import FormatStrFormatter fmtX = FormatStrFormatter('%5i') fmtY = FormatStrFormatter('%6.2f') fontsize1 = 16 # Convert everything into relative coordinates: x -= fitx.p y -= fity.p fitLineX -= fitx.p fitLineY -= fity.p # Change plate scale. x = x * ps * -1.0 y = y * ps xerr *= ps yerr *= ps fitLineX = fitLineX * ps * -1.0 fitLineY = fitLineY * ps fitSigX *= ps fitSigY *= ps paxes = py.subplot(1, Ntarg, i + 1) py.errorbar(x[idx_2015], y[idx_2015], xerr=xerr[idx_2015], yerr=yerr[idx_2015], fmt='r.', label='2015') py.errorbar(x[idx_2016], y[idx_2016], xerr=xerr[idx_2016], yerr=yerr[idx_2016], fmt='g.', label='2016') py.errorbar(x[idx_2017], y[idx_2017], xerr=xerr[idx_2017], yerr=yerr[idx_2017], fmt='b.', label='2017') py.errorbar(x[idx_2018], y[idx_2018], xerr=xerr[idx_2018], yerr=yerr[idx_2018], fmt='c.', label='2018') # if i==1: # py.yticks(np.arange(np.min(y-yerr-0.1*ps), np.max(y+yerr+0.1*ps), 0.3*ps)) # py.xticks(np.arange(np.min(x-xerr-0.1*ps), np.max(x+xerr+0.1*ps), 0.25*ps)) # else: # py.yticks(np.arange(np.min(y-yerr-0.1*ps), np.max(y+yerr+0.1*ps), 0.15*ps)) # py.xticks(np.arange(np.min(x-xerr-0.1*ps), np.max(x+xerr+0.1*ps), 0.15*ps)) paxes.tick_params(axis='both', which='major', labelsize=fontsize1) paxes.yaxis.set_major_formatter(FormatStrFormatter('%.2f')) paxes.xaxis.set_major_formatter(FormatStrFormatter('%.2f')) py.xlabel('X offset (mas)', fontsize=fontsize1) py.ylabel('Y offset (mas)', fontsize=fontsize1) py.plot(fitLineX, fitLineY, 'k-', label='_nolegend_') py.plot(fitLineX + fitSigX, fitLineY + fitSigY, 'k--', label='_nolegend_') py.plot(fitLineX - fitSigX, fitLineY - fitSigY, 'k--', label='_nolegend_') # Plot lines between observed point and the best fit value along the model line. for ee in range(len(time)): if ee in idx_2015[0].tolist(): color_line = 'red' if ee in idx_2016[0].tolist(): color_line = 'green' if ee in idx_2017[0].tolist(): color_line = 'blue' if ee in idx_2018[0].tolist(): color_line = 'cyan' py.plot([fitLineX[ee], x[ee]], [fitLineY[ee], y[ee]], color=color_line, linestyle='dashed', alpha=0.8) py.axis([xlim[i], -xlim[i], -ylim[i], ylim[i]]) py.title(starName.upper()) if i == 0: py.legend(loc=1, fontsize=12) py.subplots_adjust(wspace=0.6, hspace=0.6, left=0.08, bottom=0.05, right=0.95, top=0.90) py.tight_layout() py.show() py.savefig(filename) return
def __init__(self, root, refSrc='S1-5', align='align/align_t', imgRoot='/u/ghezgroup/data/gc/06maylgs1/clean/kp/'): self.root = root self.refSrc = refSrc self.align = align self.imgRoot = imgRoot # Read in the aligned cleaned images s = starset.StarSet(root + align) self.names = s.getArray('name') self.mag = s.getArray('mag') self.starCnt = len(s.stars) self.epochCnt = len(s.stars[0].e) # Also need coordinates relative to a bright star near # the center of the field (refSrc) rid = self.names.index(refSrc) # Read in the list of images used in the alignment listFile = open(root+align+'.list', 'r') self.files = [] for line in listFile: _data = line.split() self.files.append(_data[0]) # Get the Strehl, FWHM, and Wave front error for each image print "Reading Strehl File" strehlFile = open(imgRoot + 'irs33N.strehl', 'r') _frameno = [] _strehl = [] _wfe = [] _fwhm = [] for line in strehlFile: if (line.startswith("#")): continue _data = line.split() _frameno.append(_data[0]) _strehl.append(float(_data[1])) _wfe.append(float(_data[2])) _fwhm.append(float(_data[3])) _strehl = np.array(_strehl) _wfe = np.array(_wfe) _fwhm = np.array(_fwhm) self.strehl = np.zeros(self.epochCnt, dtype=float) self.wfe = np.zeros(self.epochCnt, dtype=float) self.fwhm = np.zeros(self.epochCnt, dtype=float) self.elevation = np.zeros(self.epochCnt, dtype=float) self.darCoeff1 = np.zeros(self.epochCnt, dtype=float) self.darCoeff2 = np.zeros(self.epochCnt, dtype=float) self.airmass = np.zeros(self.epochCnt, dtype=float) self.parang = np.zeros(self.epochCnt, dtype=float) self.horizonX = np.zeros(self.epochCnt, dtype=float) self.horizonY = np.zeros(self.epochCnt, dtype=float) self.zenithX = np.zeros(self.epochCnt, dtype=float) self.zenithY = np.zeros(self.epochCnt, dtype=float) # Get the differential atmospheric refraction coefficients # assume all stars effective wavelengths are at 2.1 microns from gcwork import astrometry as ast (refA, refB) = ast.keckDARcoeffs(2.1) ast = None for ff in range(self.epochCnt): # Find the first instance of "/c" temp1 = self.files[ff].split('/') temp2 = temp1[-1].split('_') if (temp2[0].startswith('mag')): # This is a combo image. We don't have info about this file. # We should do this one last and adopt the average of # all values. self.strehl[ff] = None self.wfe[ff] = None self.fwhm[ff] = None self.files[ff] = imgRoot + '../../combo/' + \ '_'.join(temp2[0:-1]) + '.fits' else: # Find this file idx = _frameno.index(temp2[0] + '.fits') self.strehl[ff] = _strehl[idx] self.wfe[ff] = _wfe[idx] self.fwhm[ff] = _fwhm[idx] self.files[ff] = imgRoot + temp2[0] + '.fits' # Get header info hdr = pyfits.getheader(self.files[ff]) effWave = hdr['EFFWAVE'] self.elevation[ff] = hdr['EL'] lamda = hdr['CENWAVE'] self.airmass[ff] = hdr['AIRMASS'] self.parang[ff] = hdr['PARANG'] date = hdr['DATE-OBS'].split('-') year = int(date[0]) month = int(date[1]) day = int(date[2]) utc = hdr['UTC'].split(':') hour = int(utc[0]) minute = int(utc[1]) second = int(math.floor(float(utc[2]))) utc = datetime.datetime(year, month, day, hour, minute, second) utc2hst = datetime.timedelta(hours=-10) hst = utc + utc2hst from keckdar import dar (refA, refB) = dar.keckDARcoeffs(effWave, hst.year, hst.month, hst.day, hst.hour, hst.minute) dar = None tanz = math.tan(math.radians(90.0 - self.elevation[ff])) tmp = 1 + tanz**2 self.darCoeff1[ff] = tmp * (refA + 3.0 * refB * tanz**2) self.darCoeff2[ff] = -tmp * (refA*tanz + 3.0 * refB * (tanz + 2.0*tanz**3)) # Lets determine the zenith and horizon unit vectors for # this image. pa = math.radians(self.parang[ff] + float(hdr['ROTPOSN']) - float(hdr['INSTANGL'])) self.zenithX[ff] = math.sin(pa) self.zenithY[ff] = -math.cos(pa) self.horizonX[ff] = math.cos(pa) self.horizonY[ff] = math.sin(pa) # Now for each star in each image, calculate the positional difference # between that star and the reference star. self.posx = np.zeros((self.starCnt, self.epochCnt), float) self.posy = np.zeros((self.starCnt, self.epochCnt), float) self.posh = np.zeros((self.starCnt, self.epochCnt), float) self.posz = np.zeros((self.starCnt, self.epochCnt), float) self.diffx = np.zeros((self.starCnt, self.epochCnt), float) self.diffy = np.zeros((self.starCnt, self.epochCnt), float) self.diffh = np.zeros((self.starCnt, self.epochCnt), float) self.diffz = np.zeros((self.starCnt, self.epochCnt), float) self.diffr = np.zeros((self.starCnt, self.epochCnt), float) self.difft = np.zeros((self.starCnt, self.epochCnt), float) self.dar = np.zeros((self.starCnt, self.epochCnt), dtype=float) self.diffDR = np.zeros((self.starCnt, self.epochCnt), float) self.hasData = np.zeros((self.starCnt, self.epochCnt)) # Positions and Errors to some reference source. self.avgx = np.zeros(self.starCnt, float) self.avgy = np.zeros(self.starCnt, float) self.rmsx = np.zeros(self.starCnt, float) self.rmsy = np.zeros(self.starCnt, float) self.rmsr = np.zeros(self.starCnt, float) self.rmst = np.zeros(self.starCnt, float) self.rmsRarc = np.zeros(self.starCnt, float) self.rmsTarc = np.zeros(self.starCnt, float) self.r = np.zeros(self.starCnt, float) # Get the reference coordinates at each epoch refStar = s.stars[rid] refCooX = np.zeros(self.epochCnt, float) refCooY = np.zeros(self.epochCnt, float) for ee in range(self.epochCnt): refCooX[ee] = refStar.e[ee].xorig refCooY[ee] = refStar.e[ee].yorig # Now for every epoch, compute the offset from the mean for ss in range(self.starCnt): star = s.stars[ss] # Original pixel positions xpix = star.getArrayAllEpochs('xorig') ypix = star.getArrayAllEpochs('yorig') xarc = (xpix - refCooX) * 0.00996 yarc = (ypix - refCooY) * 0.00996 # Filter out epochs with nodata idx = (np.where((xpix > -999) & (refCooX > -999)))[0] xgood = xarc[idx] ygood = yarc[idx] # Calculate the values averaged over all epochs self.avgx[ss] = xgood.mean() self.avgy[ss] = ygood.mean() self.r[ss] = np.sqrt(self.avgx[ss]**2 + self.avgy[ss]**2) self.rmsx[ss] = xgood.std() * 1000.0 self.rmsy[ss] = ygood.std() * 1000.0 # Calculate the values independently for each epoch self.posx[ss] = xarc self.posy[ss] = yarc self.posh[ss] = (xarc * self.horizonX) + (yarc * self.horizonY) self.posz[ss] = (xarc * self.zenithX) + (yarc * self.zenithY) dx = (xarc - self.avgx[ss]) * 1000.0 dy = (yarc - self.avgy[ss]) * 1000.0 avgX = self.avgx[ss] avgY = self.avgy[ss] avgR = np.sqrt(avgX**2 + avgY**2) # Convert into zenith (Y) and horizon(X) coordinates self.diffx[ss] = dx self.diffy[ss] = dy self.diffh[ss] = (dx * self.horizonX) + (dy * self.horizonY) self.diffz[ss] = (dx * self.zenithX) + (dy * self.zenithY) self.diffr[ss] = ((dx * avgX) + (dy * avgY)) / avgR self.difft[ss] = ((dx * -avgY) + (dy * avgX)) / avgR self.hasData[ss,idx] += 1 self.hasData[ss, 0] = 0 # Turn off the combo epoch # Compute the predicted differential atmospheric refraction # between this star and the reference star in each of the # observed images. deltaZ = self.posz[ss] / 206265.0 deltaR = self.darCoeff1 * deltaZ deltaR += self.darCoeff2 * deltaZ * abs(deltaZ) deltaR *= 206265.0 self.dar[ss] = deltaR avgDR = deltaR[idx].mean() self.diffDR[ss] = (deltaR - avgDR) * 1000.0 savefile = '%s/tables/pairwise_wrt_%s.pickle' % \ (self.root, self.refSrc) _save = open(savefile, 'w') pickle.dump(self, _save) _save.close()