def kepdeltapix(infile, nexp, columns, rows, fluxes, prfdir, interpolation, tolerance, fittype, imscale, colmap, verbose, logfile, status, cmdLine=False): # input arguments status = 0 seterr(all="ignore") # log the call hashline = '----------------------------------------------------------------------------' kepmsg.log(logfile, hashline, verbose) call = 'KEPDELTAPIX -- ' call += 'infile=' + infile + ' ' call += 'nexp=' + str(nexp) + ' ' call += 'columns=' + columns + ' ' call += 'rows=' + rows + ' ' call += 'fluxes=' + fluxes + ' ' call += 'prfdir=' + prfdir + ' ' call += 'interpolation=' + interpolation + ' ' call += 'tolerance=' + str(tolerance) + ' ' call += 'fittype=' + str(fittype) + ' ' call += 'imscale=' + imscale + ' ' call += 'colmap=' + colmap + ' ' chatter = 'n' if (verbose): chatter = 'y' call += 'verbose=' + chatter + ' ' call += 'logfile=' + logfile kepmsg.log(logfile, call + '\n', verbose) # test log file logfile = kepmsg.test(logfile) # start time kepmsg.clock('KEPDELTAPIX started at', logfile, verbose) # reference color map if colmap == 'browse': status = cmap_plot(cmdLine) # open TPF FITS file if status == 0: try: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, barytime, status = \ kepio.readTPF(infile,'TIME',logfile,verbose) except: message = 'ERROR -- KEPDELTAPIX: is %s a Target Pixel File? ' % infile status = kepmsg.err(logfile, message, verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, tcorr, status = \ kepio.readTPF(infile,'TIMECORR',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, cadno, status = \ kepio.readTPF(infile,'CADENCENO',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, fluxpixels, status = \ kepio.readTPF(infile,'FLUX',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, errpixels, status = \ kepio.readTPF(infile,'FLUX_ERR',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, qual, status = \ kepio.readTPF(infile,'QUALITY',logfile,verbose) # print target data if status == 0 and verbose: print '' print ' KepID: %s' % kepid print ' RA (J2000): %s' % ra print 'Dec (J2000): %s' % dec print ' KepMag: %s' % kepmag print ' SkyGroup: %2s' % skygroup print ' Season: %2s' % str(season) print ' Channel: %2s' % channel print ' Module: %2s' % module print ' Output: %1s' % output print '' # determine suitable PRF calibration file if status == 0: if int(module) < 10: prefix = 'kplr0' else: prefix = 'kplr' prfglob = prfdir + '/' + prefix + str(module) + '.' + str( output) + '*' + '_prf.fits' try: prffile = glob.glob(prfglob)[0] except: message = 'ERROR -- KEPDELTAPIX: No PRF file found in ' + prfdir status = kepmsg.err(logfile, message, verbose) # read PRF images if status == 0: prfn = [0, 0, 0, 0, 0] crpix1p = numpy.zeros((5), dtype='float32') crpix2p = numpy.zeros((5), dtype='float32') crval1p = numpy.zeros((5), dtype='float32') crval2p = numpy.zeros((5), dtype='float32') cdelt1p = numpy.zeros((5), dtype='float32') cdelt2p = numpy.zeros((5), dtype='float32') for i in range(5): prfn[i], crpix1p[i], crpix2p[i], crval1p[i], crval2p[i], cdelt1p[i], cdelt2p[i], status \ = kepio.readPRFimage(prffile,i+1,logfile,verbose) # choose rows in the TPF table at random if status == 0: i = 0 rownum = [] while i < nexp: work = int(random.random() * len(barytime)) if numpy.isfinite(barytime[work]) and numpy.isfinite( fluxpixels[work, ydim * xdim / 2]): rownum.append(work) i += 1 # construct input pixel image if status == 0: fscat = numpy.empty((len(fluxes), nexp), dtype='float32') xscat = numpy.empty((len(columns), nexp), dtype='float32') yscat = numpy.empty((len(rows), nexp), dtype='float32') for irow in range(nexp): flux = fluxpixels[rownum[irow], :] # image scale and intensity limits of pixel data if status == 0: flux_pl, zminfl, zmaxfl = kepplot.intScale1D(flux, imscale) n = 0 imgflux_pl = empty((ydim, xdim)) for i in range(ydim): for j in range(xdim): imgflux_pl[i, j] = flux_pl[n] n += 1 # fit PRF model to pixel data if status == 0: start = time.time() f, y, x, prfMod, prfFit, prfRes = kepfit.fitMultiPRF( flux, ydim, xdim, column, row, prfn, crval1p, crval2p, cdelt1p, cdelt2p, interpolation, tolerance, fluxes, columns, rows, fittype, verbose, logfile) if verbose: print '\nConvergence time = %.1fs' % (time.time() - start) # best fit parameters if status == 0: for i in range(len(f)): fscat[i, irow] = f[i] xscat[i, irow] = x[i] yscat[i, irow] = y[i] # replace starting guess with previous fit parameters if status == 0: fluxes = copy(f) columns = copy(x) rows = copy(y) # mean and rms results if status == 0: fmean = [] fsig = [] xmean = [] xsig = [] ymean = [] ysig = [] for i in range(len(f)): fmean.append(numpy.mean(fscat[i, :])) xmean.append(numpy.mean(xscat[i, :])) ymean.append(numpy.mean(yscat[i, :])) fsig.append(numpy.std(fscat[i, :])) xsig.append(numpy.std(xscat[i, :])) ysig.append(numpy.std(yscat[i, :])) txt = 'Flux = %10.2f e-/s ' % fmean[-1] txt += 'X = %7.4f +/- %6.4f pix ' % (xmean[-1], xsig[i]) txt += 'Y = %7.4f +/- %6.4f pix' % (ymean[-1], ysig[i]) kepmsg.log(logfile, txt, True) # output results for kepprfphot if status == 0: txt1 = 'columns=0.0' txt2 = ' rows=0.0' for i in range(1, len(f)): txt1 += ',%.4f' % (xmean[i] - xmean[0]) txt2 += ',%.4f' % (ymean[i] - ymean[0]) kepmsg.log(logfile, '\nkepprfphot input fields:', True) kepmsg.log(logfile, txt1, True) kepmsg.log(logfile, txt2, True) # image scale and intensity limits for PRF model image if status == 0: imgprf_pl, zminpr, zmaxpr = kepplot.intScale2D(prfMod, imscale) # image scale and intensity limits for PRF fit image if status == 0: imgfit_pl, zminfi, zmaxfi = kepplot.intScale2D(prfFit, imscale) # image scale and intensity limits for data - fit residual if status == 0: imgres_pl, zminre, zmaxre = kepplot.intScale2D(prfRes, imscale) # plot style if status == 0: try: params = { 'backend': 'png', 'axes.linewidth': 2.5, 'axes.labelsize': 24, 'axes.font': 'sans-serif', 'axes.fontweight': 'bold', 'text.fontsize': 12, 'legend.fontsize': 12, 'xtick.labelsize': 10, 'ytick.labelsize': 10 } pylab.rcParams.update(params) except: pass pylab.figure(figsize=[10, 10]) pylab.clf() plotimage(imgflux_pl, zminfl, zmaxfl, 1, row, column, xdim, ydim, 0.06, 0.52, 'flux', colmap) plotimage(imgfit_pl, zminfl, zmaxfl, 3, row, column, xdim, ydim, 0.06, 0.06, 'fit', colmap) plotimage(imgres_pl, zminfl, zmaxfl, 4, row, column, xdim, ydim, 0.52, 0.06, 'residual', colmap) plotimage(imgprf_pl, zminpr, zmaxpr * 0.9, 2, row, column, xdim, ydim, 0.52, 0.52, 'model', colmap) for i in range(len(f)): pylab.plot(xscat[i, :], yscat[i, :], 'o', color='k') # Plot creep of target position over time, relative to the central source # barytime0 = float(int(barytime[0] / 100) * 100.0) # barytime -= barytime0 # xlab = 'BJD $-$ %d' % barytime0 # xmin = numpy.nanmin(barytime) # xmax = numpy.nanmax(barytime) # y1min = numpy.nanmin(data) # y1max = numpy.nanmax(data) # xr = xmax - xmin # yr = ymax - ymin # barytime = insert(barytime,[0],[barytime[0]]) # barytime = append(barytime,[barytime[-1]]) # data = insert(data,[0],[0.0]) # data = append(data,0.0) # # pylab.figure(2,figsize=[10,10]) # pylab.clf() # ax = pylab.subplot(211) # pylab.subplots_adjust(0.1,0.5,0.88,0.42) # pylab.gca().xaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) # pylab.gca().yaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) # labels = ax.get_yticklabels() # setp(labels, 'rotation', 90, fontsize=ticksize) # for i in range(1,len(f)): # pylab.plot(rownum,xscat[i,:]-xscat[0,:],'o') # pylab.ylabel('$\Delta$Columns', {'color' : 'k'}) # ax = pylab.subplot(211) # pylab.subplots_adjust(0.1,0.1,0.88,0.42) # pylab.gca().xaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) # pylab.gca().yaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) # labels = ax.get_yticklabels() # setp(labels, 'rotation', 90, fontsize=ticksize) # for i in range(1,len(f)): # pylab.plot(rownum,yscat[i,:]-yscat[0,:],'o') # pylab.xlim(xmin-xr*0.01,xmax+xr*0.01) # if ymin-yr*0.01 <= 0.0 or fullrange: # pylab.ylim(1.0e-10,ymax+yr*0.01) # else: # pylab.ylim(ymin-yr*0.01,ymax+yr*0.01) # pylab.ylabel('$\Delta$Rows', {'color' : 'k'}) # pylab.xlabel(xlab, {'color' : 'k'}) # render plot if status == 0: if cmdLine: pylab.show(block=True) else: pylab.ion() pylab.plot([]) pylab.ioff() # stop time kepmsg.clock('\nKEPDELTAPIX ended at', logfile, verbose) return
def kepprf(infile,plotfile,rownum,columns,rows,fluxes,border,background,focus,prfdir,xtol,ftol, imscale,colmap,labcol,apercol,plt,verbose,logfile,status,cmdLine=False): # input arguments status = 0 seterr(all="ignore") # log the call hashline = '----------------------------------------------------------------------------' kepmsg.log(logfile,hashline,verbose) call = 'KEPPRF -- ' call += 'infile='+infile+' ' call += 'plotfile='+plotfile+' ' call += 'rownum='+str(rownum)+' ' call += 'columns='+columns+' ' call += 'rows='+rows+' ' call += 'fluxes='+fluxes+' ' call += 'border='+str(border)+' ' bground = 'n' if (background): bground = 'y' call += 'background='+bground+' ' focs = 'n' if (focus): focs = 'y' call += 'focus='+focs+' ' call += 'prfdir='+prfdir+' ' call += 'xtol='+str(xtol)+' ' call += 'ftol='+str(xtol)+' ' call += 'imscale='+imscale+' ' call += 'colmap='+colmap+' ' call += 'labcol='+labcol+' ' call += 'apercol='+apercol+' ' plotit = 'n' if (plt): plotit = 'y' call += 'plot='+plotit+' ' chatter = 'n' if (verbose): chatter = 'y' call += 'verbose='+chatter+' ' call += 'logfile='+logfile kepmsg.log(logfile,call+'\n',verbose) # test log file logfile = kepmsg.test(logfile) # start time kepmsg.clock('KEPPRF started at',logfile,verbose) # reference color map if colmap == 'browse': status = cmap_plot(cmdLine) # construct inital guess vector for fit if status == 0: guess = [] try: f = fluxes.strip().split(',') x = columns.strip().split(',') y = rows.strip().split(',') for i in xrange(len(f)): f[i] = float(f[i]) except: f = fluxes x = columns y = rows nsrc = len(f) for i in xrange(nsrc): try: guess.append(float(f[i])) except: message = 'ERROR -- KEPPRF: Fluxes must be floating point numbers' status = kepmsg.err(logfile,message,verbose) if status == 0: if len(x) != nsrc or len(y) != nsrc: message = 'ERROR -- KEPFIT:FITMULTIPRF: Guesses for rows, columns and ' message += 'fluxes must have the same number of sources' status = kepmsg.err(logfile,message,verbose) if status == 0: for i in xrange(nsrc): try: guess.append(float(x[i])) except: message = 'ERROR -- KEPPRF: Columns must be floating point numbers' status = kepmsg.err(logfile,message,verbose) if status == 0: for i in xrange(nsrc): try: guess.append(float(y[i])) except: message = 'ERROR -- KEPPRF: Rows must be floating point numbers' status = kepmsg.err(logfile,message,verbose) if status == 0 and background: if border == 0: guess.append(0.0) else: for i in range((border+1)*2): guess.append(0.0) if status == 0 and focus: guess.append(1.0); guess.append(1.0); guess.append(0.0) # open TPF FITS file if status == 0: try: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, barytime, status = \ kepio.readTPF(infile,'TIME',logfile,verbose) except: message = 'ERROR -- KEPPRF: is %s a Target Pixel File? ' % infile status = kepmsg.err(logfile,message,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, tcorr, status = \ kepio.readTPF(infile,'TIMECORR',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, cadno, status = \ kepio.readTPF(infile,'CADENCENO',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, fluxpixels, status = \ kepio.readTPF(infile,'FLUX',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, errpixels, status = \ kepio.readTPF(infile,'FLUX_ERR',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, qual, status = \ kepio.readTPF(infile,'QUALITY',logfile,verbose) # read mask defintion data from TPF file if status == 0: maskimg, pixcoord1, pixcoord2, status = kepio.readMaskDefinition(infile,logfile,verbose) npix = numpy.size(numpy.nonzero(maskimg)[0]) # print target data if status == 0 and verbose: print '' print ' KepID: %s' % kepid print ' BJD: %.2f' % (barytime[rownum-1] + 2454833.0) print ' RA (J2000): %s' % ra print 'Dec (J2000): %s' % dec print ' KepMag: %s' % kepmag print ' SkyGroup: %2s' % skygroup print ' Season: %2s' % str(season) print ' Channel: %2s' % channel print ' Module: %2s' % module print ' Output: %1s' % output print '' # is this a good row with finite timestamp and pixels? if status == 0: if not numpy.isfinite(barytime[rownum-1]) or numpy.nansum(fluxpixels[rownum-1,:]) == numpy.nan: message = 'ERROR -- KEPFIELD: Row ' + str(rownum) + ' is a bad quality timestamp' status = kepmsg.err(logfile,message,verbose) # construct input pixel image if status == 0: flux = fluxpixels[rownum-1,:] ferr = errpixels[rownum-1,:] DATx = arange(column,column+xdim) DATy = arange(row,row+ydim) # if numpy.nanmin > 420000.0: flux -= 420000.0 # image scale and intensity limits of pixel data if status == 0: n = 0 DATimg = empty((ydim,xdim)) ERRimg = empty((ydim,xdim)) for i in range(ydim): for j in range(xdim): DATimg[i,j] = flux[n] ERRimg[i,j] = ferr[n] n += 1 # determine suitable PRF calibration file if status == 0: if int(module) < 10: prefix = 'kplr0' else: prefix = 'kplr' prfglob = prfdir + '/' + prefix + str(module) + '.' + str(output) + '*' + '_prf.fits' try: prffile = glob.glob(prfglob)[0] except: message = 'ERROR -- KEPPRF: No PRF file found in ' + prfdir status = kepmsg.err(logfile,message,verbose) # read PRF images if status == 0: prfn = [0,0,0,0,0] crpix1p = numpy.zeros((5),dtype='float32') crpix2p = numpy.zeros((5),dtype='float32') crval1p = numpy.zeros((5),dtype='float32') crval2p = numpy.zeros((5),dtype='float32') cdelt1p = numpy.zeros((5),dtype='float32') cdelt2p = numpy.zeros((5),dtype='float32') for i in range(5): prfn[i], crpix1p[i], crpix2p[i], crval1p[i], crval2p[i], cdelt1p[i], cdelt2p[i], status \ = kepio.readPRFimage(prffile,i+1,logfile,verbose) prfn = array(prfn) PRFx = arange(0.5,shape(prfn[0])[1]+0.5) PRFy = arange(0.5,shape(prfn[0])[0]+0.5) PRFx = (PRFx - size(PRFx) / 2) * cdelt1p[0] PRFy = (PRFy - size(PRFy) / 2) * cdelt2p[0] # interpolate the calibrated PRF shape to the target position if status == 0: prf = zeros(shape(prfn[0]),dtype='float32') prfWeight = zeros((5),dtype='float32') for i in xrange(5): prfWeight[i] = sqrt((column - crval1p[i])**2 + (row - crval2p[i])**2) if prfWeight[i] == 0.0: prfWeight[i] = 1.0e-6 prf = prf + prfn[i] / prfWeight[i] prf = prf / nansum(prf) / cdelt1p[0] / cdelt2p[0] # interpolate the calibrated PRF shape to the target position # if status == 0: # prf = zeros(shape(prfn[0,:,:]),dtype='float32') # px = crval1p + len(PRFx) / 2 * cdelt1p[0] # py = crval2p + len(PRFy) / 2 * cdelt2p[0] # pp = [[px[0],py[0]], # [px[1],py[1]], # [px[2],py[2]], # [px[3],py[3]], # [px[4],py[4]]] # for index,value in ndenumerate(prf): # pz = prfn[:,index[0],index[1]] # prf[index] = griddata(pp, pz, ([column], [row]), method='linear') # print shape(prf) # location of the data image centered on the PRF image (in PRF pixel units) if status == 0: prfDimY = int(ydim / cdelt1p[0]) prfDimX = int(xdim / cdelt2p[0]) PRFy0 = (shape(prf)[0] - prfDimY) / 2 PRFx0 = (shape(prf)[1] - prfDimX) / 2 # interpolation function over the PRF if status == 0: splineInterpolation = scipy.interpolate.RectBivariateSpline(PRFx,PRFy,prf) # construct mesh for background model if status == 0 and background: bx = numpy.arange(1.,float(xdim+1)) by = numpy.arange(1.,float(ydim+1)) xx, yy = numpy.meshgrid(numpy.linspace(bx.min(), bx.max(), xdim), numpy.linspace(by.min(), by.max(), ydim)) # fit PRF model to pixel data if status == 0: start = time.time() if focus and background: args = (DATx,DATy,DATimg,ERRimg,nsrc,border,xx,yy,splineInterpolation,float(x[0]),float(y[0])) ans = fmin_powell(kepfunc.PRFwithFocusAndBackground,guess,args=args,xtol=xtol, ftol=ftol,disp=False) elif focus and not background: args = (DATx,DATy,DATimg,ERRimg,nsrc,splineInterpolation,float(x[0]),float(y[0])) ans = fmin_powell(kepfunc.PRFwithFocus,guess,args=args,xtol=xtol, ftol=ftol,disp=False) elif background and not focus: args = (DATx,DATy,DATimg,ERRimg,nsrc,border,xx,yy,splineInterpolation,float(x[0]),float(y[0])) ans = fmin_powell(kepfunc.PRFwithBackground,guess,args=args,xtol=xtol, ftol=ftol,disp=False) else: args = (DATx,DATy,DATimg,ERRimg,nsrc,splineInterpolation,float(x[0]),float(y[0])) ans = fmin_powell(kepfunc.PRF,guess,args=args,xtol=xtol, ftol=ftol,disp=False) print 'Convergence time = %.2fs\n' % (time.time() - start) # pad the PRF data if the PRF array is smaller than the data array if status == 0: flux = []; OBJx = []; OBJy = [] PRFmod = numpy.zeros((prfDimY,prfDimX)) if PRFy0 < 0 or PRFx0 < 0.0: PRFmod = numpy.zeros((prfDimY,prfDimX)) superPRF = zeros((prfDimY+1,prfDimX+1)) superPRF[abs(PRFy0):abs(PRFy0)+shape(prf)[0],abs(PRFx0):abs(PRFx0)+shape(prf)[1]] = prf prf = superPRF * 1.0 PRFy0 = 0 PRFx0 = 0 # rotate the PRF model around its center if focus: angle = ans[-1] prf = rotate(prf,-angle,reshape=False,mode='nearest') # iterate through the sources in the best fit PSF model for i in range(nsrc): flux.append(ans[i]) OBJx.append(ans[nsrc+i]) OBJy.append(ans[nsrc*2+i]) # calculate best-fit model y = (OBJy[i]-mean(DATy)) / cdelt1p[0] x = (OBJx[i]-mean(DATx)) / cdelt2p[0] prfTmp = shift(prf,[y,x],order=3,mode='constant') prfTmp = prfTmp[PRFy0:PRFy0+prfDimY,PRFx0:PRFx0+prfDimX] PRFmod = PRFmod + prfTmp * flux[i] wx = 1.0 wy = 1.0 angle = 0 b = 0.0 # write out best fit parameters if verbose: txt = 'Flux = %10.2f e-/s ' % flux[i] txt += 'X = %9.4f pix ' % OBJx[i] txt += 'Y = %9.4f pix ' % OBJy[i] kepmsg.log(logfile,txt,True) # # params = {'backend': 'png', # 'axes.linewidth': 2.5, # 'axes.labelsize': 24, # 'axes.font': 'sans-serif', # 'axes.fontweight' : 'bold', # 'text.fontsize': 12, # 'legend.fontsize': 12, # 'xtick.labelsize': 24, # 'ytick.labelsize': 24} # pylab.rcParams.update(params) # # pylab.figure(figsize=[20,10]) # ax = pylab.axes([0.05,0.08,0.46,0.9]) # xxx = numpy.arange(397.5,402.5,0.02) # yyy = numpy.sum(PRFmod,axis=0) / numpy.max(numpy.sum(PRFmod,axis=0)) # pylab.plot(xxx,yyy,color='b',linewidth=3.0) # xxx = numpy.append(numpy.insert(xxx,[0],[xxx[0]]),xxx[-1]) # yyy = numpy.append(numpy.insert(yyy,[0],[0.0]),yyy[-1]) # pylab.fill(xxx,yyy,fc='y',linewidth=0.0,alpha=0.3) # pylab.xlabel('Pixel Column Number') # pylab.xlim(397.5,402.5) # pylab.ylim(1.0e-30,1.02) # for xmaj in numpy.arange(397.5,402.5,1.0): # pylab.plot([xmaj,xmaj],[0.0,1.1],color='k',linewidth=0.5,linestyle=':') # for xmaj in numpy.arange(0.2,1.2,0.2): # pylab.plot([0.0,2000.0],[xmaj,xmaj],color='k',linewidth=0.5,linestyle=':') # # # ax = pylab.axes([0.51,0.08,0.46,0.9]) # xxx = numpy.arange(32.5,37.5,0.02) # yyy = numpy.sum(PRFmod,axis=1) / numpy.max(numpy.sum(PRFmod,axis=1)) # pylab.plot(xxx,yyy,color='b',linewidth=3.0) # xxx = numpy.append(numpy.insert(xxx,[0],[xxx[0]]),xxx[-1]) # yyy = numpy.append(numpy.insert(yyy,[0],[0.0]),yyy[-1]) # pylab.fill(xxx,yyy,fc='y',linewidth=0.0,alpha=0.3) # pylab.setp(pylab.gca(),yticklabels=[]) # pylab.xlabel('Pixel Row Number') # pylab.xlim(32.5,37.5) # pylab.ylim(1.0e-30,1.02) # for xmaj in numpy.arange(32.5,37.5,1.0): # pylab.plot([xmaj,xmaj],[0.0,1.1],color='k',linewidth=0.5,linestyle=':') # for xmaj in numpy.arange(0.2,1.2,0.2): # pylab.plot([0.0,2000.0],[xmaj,xmaj],color='k',linewidth=0.5,linestyle=':') # pylab.ion() # pylab.plot([]) # pylab.ioff() if verbose and background: bterms = border + 1 if bterms == 1: b = ans[nsrc*3] else: bcoeff = array([ans[nsrc*3:nsrc*3+bterms],ans[nsrc*3+bterms:nsrc*3+bterms*2]]) bkg = kepfunc.polyval2d(xx,yy,bcoeff) b = nanmean(bkg.reshape(bkg.size)) txt = '\n Mean background = %.2f e-/s' % b kepmsg.log(logfile,txt,True) if focus: wx = ans[-3] wy = ans[-2] angle = ans[-1] if verbose and focus: if not background: kepmsg.log(logfile,'',True) kepmsg.log(logfile,' X/Y focus factors = %.3f/%.3f' % (wx,wy),True) kepmsg.log(logfile,'PRF rotation angle = %.2f deg' % angle,True) # measure flux fraction and contamination if status == 0: PRFall = kepfunc.PRF2DET(flux,OBJx,OBJy,DATx,DATy,wx,wy,angle,splineInterpolation) PRFone = kepfunc.PRF2DET([flux[0]],[OBJx[0]],[OBJy[0]],DATx,DATy,wx,wy,angle,splineInterpolation) FluxInMaskAll = numpy.nansum(PRFall) FluxInMaskOne = numpy.nansum(PRFone) FluxInAperAll = 0.0 FluxInAperOne = 0.0 for i in range(1,ydim): for j in range(1,xdim): if kepstat.bitInBitmap(maskimg[i,j],2): FluxInAperAll += PRFall[i,j] FluxInAperOne += PRFone[i,j] FluxFraction = FluxInAperOne / flux[0] try: Contamination = (FluxInAperAll - FluxInAperOne) / FluxInAperAll except: Contamination = 0.0 kepmsg.log(logfile,'\n Total flux in mask = %.2f e-/s' % FluxInMaskAll,True) kepmsg.log(logfile,' Target flux in mask = %.2f e-/s' % FluxInMaskOne,True) kepmsg.log(logfile,' Total flux in aperture = %.2f e-/s' % FluxInAperAll,True) kepmsg.log(logfile,' Target flux in aperture = %.2f e-/s' % FluxInAperOne,True) kepmsg.log(logfile,' Target flux fraction in aperture = %.2f%%' % (FluxFraction * 100.0),True) kepmsg.log(logfile,'Contamination fraction in aperture = %.2f%%' % (Contamination * 100.0),True) # constuct model PRF in detector coordinates if status == 0: PRFfit = PRFall + 0.0 if background and bterms == 1: PRFfit = PRFall + b if background and bterms > 1: PRFfit = PRFall + bkg # calculate residual of DATA - FIT if status == 0: PRFres = DATimg - PRFfit FLUXres = numpy.nansum(PRFres) / npix # calculate the sum squared difference between data and model if status == 0: Pearson = abs(numpy.nansum(numpy.square(DATimg - PRFfit) / PRFfit)) Chi2 = numpy.nansum(numpy.square(DATimg - PRFfit) / numpy.square(ERRimg)) DegOfFreedom = npix - len(guess) - 1 try: kepmsg.log(logfile,'\n Residual flux = %.2f e-/s' % FLUXres,True) kepmsg.log(logfile,'Pearson\'s chi^2 test = %d for %d dof' % (Pearson,DegOfFreedom),True) except: pass kepmsg.log(logfile,' Chi^2 test = %d for %d dof' % (Chi2,DegOfFreedom),True) # image scale and intensity limits for plotting images if status == 0: imgdat_pl, zminfl, zmaxfl = kepplot.intScale2D(DATimg,imscale) imgprf_pl, zminpr, zmaxpr = kepplot.intScale2D(PRFmod,imscale) imgfit_pl, zminfi, zmaxfi = kepplot.intScale2D(PRFfit,imscale) imgres_pl, zminre, zmaxre = kepplot.intScale2D(PRFres,'linear') if imscale == 'linear': zmaxpr *= 0.9 elif imscale == 'logarithmic': zmaxpr = numpy.max(zmaxpr) zminpr = zmaxpr / 2 # plot style if status == 0: try: params = {'backend': 'png', 'axes.linewidth': 2.5, 'axes.labelsize': 28, 'axes.font': 'sans-serif', 'axes.fontweight' : 'bold', 'text.fontsize': 12, 'legend.fontsize': 12, 'xtick.labelsize': 20, 'ytick.labelsize': 20, 'xtick.major.pad': 6, 'ytick.major.pad': 6} pylab.rcParams.update(params) except: pass pylab.figure(figsize=[12,10]) pylab.clf() plotimage(imgdat_pl,zminfl,zmaxfl,1,row,column,xdim,ydim,0.07,0.53,'observation',colmap,labcol) # pylab.text(830.0,242.1,'A',horizontalalignment='center',verticalalignment='center', # fontsize=28,fontweight=500,color='white') # pylab.text(831.1,240.62,'B',horizontalalignment='center',verticalalignment='center', # fontsize=28,fontweight=500,color='white') # plotimage(imgprf_pl,0.0,zmaxpr/0.5,2,row,column,xdim,ydim,0.52,0.52,'model',colmap) plotimage(imgprf_pl,zminpr,zmaxpr,2,row,column,xdim,ydim,0.44,0.53,'model',colmap,labcol) kepplot.borders(maskimg,xdim,ydim,pixcoord1,pixcoord2,1,apercol,'--',0.5) kepplot.borders(maskimg,xdim,ydim,pixcoord1,pixcoord2,2,apercol,'-',3.0) plotimage(imgfit_pl,zminfl,zmaxfl,3,row,column,xdim,ydim,0.07,0.08,'fit',colmap,labcol) # plotimage(imgres_pl,-zmaxre,zmaxre,4,row,column,xdim,ydim,0.44,0.08,'residual',colmap,'k') plotimage(imgres_pl,zminfl,zmaxfl,4,row,column,xdim,ydim,0.44,0.08,'residual',colmap,labcol) # plot data color bar # barwin = pylab.axes([0.84,0.53,0.06,0.45]) barwin = pylab.axes([0.84,0.08,0.06,0.9]) if imscale == 'linear': brange = numpy.arange(zminfl,zmaxfl,(zmaxfl-zminfl)/1000) elif imscale == 'logarithmic': brange = numpy.arange(10.0**zminfl,10.0**zmaxfl,(10.0**zmaxfl-10.0**zminfl)/1000) elif imscale == 'squareroot': brange = numpy.arange(zminfl**2,zmaxfl**2,(zmaxfl**2-zminfl**2)/1000) if imscale == 'linear': barimg = numpy.resize(brange,(1000,1)) elif imscale == 'logarithmic': barimg = numpy.log10(numpy.resize(brange,(1000,1))) elif imscale == 'squareroot': barimg = numpy.sqrt(numpy.resize(brange,(1000,1))) try: nrm = len(str(int(numpy.nanmax(brange))))-1 except: nrm = 0 brange = brange / 10**nrm pylab.imshow(barimg,aspect='auto',interpolation='nearest',origin='lower', vmin=numpy.nanmin(barimg),vmax=numpy.nanmax(barimg), extent=(0.0,1.0,brange[0],brange[-1]),cmap=colmap) barwin.yaxis.tick_right() barwin.yaxis.set_label_position('right') barwin.yaxis.set_major_locator(MaxNLocator(7)) pylab.gca().yaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.gca().set_autoscale_on(False) pylab.setp(pylab.gca(),xticklabels=[],xticks=[]) pylab.ylabel('Flux (10$^%d$ e$^-$ s$^{-1}$)' % nrm) setp(barwin.get_yticklabels(), 'rotation', 90) barwin.yaxis.set_major_formatter(ticker.FormatStrFormatter('%.1f')) # plot residual color bar # barwin = pylab.axes([0.84,0.08,0.06,0.45]) # Brange = numpy.arange(-zmaxre,zmaxre,(zmaxre+zmaxre)/1000) # try: # nrm = len(str(int(numpy.nanmax(brange))))-1 # except: # nrm = 0 # brange = brange / 10**nrm # barimg = numpy.resize(brange,(1000,1)) # pylab.imshow(barimg,aspect='auto',interpolation='nearest',origin='lower', # vmin=brange[0],vmax=brange[-1],extent=(0.0,1.0,brange[0],brange[-1]),cmap=colmap) # barwin.yaxis.tick_right() # barwin.yaxis.set_label_position('right') # barwin.yaxis.set_major_formatter(ticker.FormatStrFormatter('%.1f')) # barwin.yaxis.set_major_locator(MaxNLocator(7)) # pylab.gca().yaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) # pylab.gca().set_autoscale_on(False) # pylab.setp(pylab.gca(),xticklabels=[],xticks=[]) # pylab.ylabel('Residual (10$^%d$ e$^-$ s$^{-1}$)' % nrm) # setp(barwin.get_yticklabels(), 'rotation', 90) # render plot if status == 0 and len(plotfile) > 0 and plotfile.lower() != 'none': pylab.savefig(plotfile) if status == 0 and plt: if cmdLine: pylab.show(block=True) else: pylab.ion() pylab.plot([]) pylab.ioff() # stop time kepmsg.clock('\nKEPPRF ended at',logfile,verbose) return
def kepprf(infile, plotfile, rownum, columns, rows, fluxes, border, background, focus, prfdir, xtol, ftol, imscale, colmap, labcol, apercol, plt, verbose, logfile, status, cmdLine=False): # input arguments status = 0 seterr(all="ignore") # log the call hashline = '----------------------------------------------------------------------------' kepmsg.log(logfile, hashline, verbose) call = 'KEPPRF -- ' call += 'infile=' + infile + ' ' call += 'plotfile=' + plotfile + ' ' call += 'rownum=' + str(rownum) + ' ' call += 'columns=' + columns + ' ' call += 'rows=' + rows + ' ' call += 'fluxes=' + fluxes + ' ' call += 'border=' + str(border) + ' ' bground = 'n' if (background): bground = 'y' call += 'background=' + bground + ' ' focs = 'n' if (focus): focs = 'y' call += 'focus=' + focs + ' ' call += 'prfdir=' + prfdir + ' ' call += 'xtol=' + str(xtol) + ' ' call += 'ftol=' + str(xtol) + ' ' call += 'imscale=' + imscale + ' ' call += 'colmap=' + colmap + ' ' call += 'labcol=' + labcol + ' ' call += 'apercol=' + apercol + ' ' plotit = 'n' if (plt): plotit = 'y' call += 'plot=' + plotit + ' ' chatter = 'n' if (verbose): chatter = 'y' call += 'verbose=' + chatter + ' ' call += 'logfile=' + logfile kepmsg.log(logfile, call + '\n', verbose) # test log file logfile = kepmsg.test(logfile) # start time kepmsg.clock('KEPPRF started at', logfile, verbose) # reference color map if colmap == 'browse': status = cmap_plot(cmdLine) # construct inital guess vector for fit if status == 0: guess = [] try: f = fluxes.strip().split(',') x = columns.strip().split(',') y = rows.strip().split(',') for i in range(len(f)): f[i] = float(f[i]) except: f = fluxes x = columns y = rows nsrc = len(f) for i in range(nsrc): try: guess.append(float(f[i])) except: message = 'ERROR -- KEPPRF: Fluxes must be floating point numbers' status = kepmsg.err(logfile, message, verbose) if status == 0: if len(x) != nsrc or len(y) != nsrc: message = 'ERROR -- KEPFIT:FITMULTIPRF: Guesses for rows, columns and ' message += 'fluxes must have the same number of sources' status = kepmsg.err(logfile, message, verbose) if status == 0: for i in range(nsrc): try: guess.append(float(x[i])) except: message = 'ERROR -- KEPPRF: Columns must be floating point numbers' status = kepmsg.err(logfile, message, verbose) if status == 0: for i in range(nsrc): try: guess.append(float(y[i])) except: message = 'ERROR -- KEPPRF: Rows must be floating point numbers' status = kepmsg.err(logfile, message, verbose) if status == 0 and background: if border == 0: guess.append(0.0) else: for i in range((border + 1) * 2): guess.append(0.0) if status == 0 and focus: guess.append(1.0) guess.append(1.0) guess.append(0.0) # open TPF FITS file if status == 0: try: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, barytime, status = \ kepio.readTPF(infile,'TIME',logfile,verbose) except: message = 'ERROR -- KEPPRF: is %s a Target Pixel File? ' % infile status = kepmsg.err(logfile, message, verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, tcorr, status = \ kepio.readTPF(infile,'TIMECORR',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, cadno, status = \ kepio.readTPF(infile,'CADENCENO',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, fluxpixels, status = \ kepio.readTPF(infile,'FLUX',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, errpixels, status = \ kepio.readTPF(infile,'FLUX_ERR',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, qual, status = \ kepio.readTPF(infile,'QUALITY',logfile,verbose) # read mask defintion data from TPF file if status == 0: maskimg, pixcoord1, pixcoord2, status = kepio.readMaskDefinition( infile, logfile, verbose) npix = numpy.size(numpy.nonzero(maskimg)[0]) # print target data if status == 0 and verbose: print('') print(' KepID: %s' % kepid) print(' BJD: %.2f' % (barytime[rownum - 1] + 2454833.0)) print(' RA (J2000): %s' % ra) print('Dec (J2000): %s' % dec) print(' KepMag: %s' % kepmag) print(' SkyGroup: %2s' % skygroup) print(' Season: %2s' % str(season)) print(' Channel: %2s' % channel) print(' Module: %2s' % module) print(' Output: %1s' % output) print('') # is this a good row with finite timestamp and pixels? if status == 0: if not numpy.isfinite(barytime[rownum - 1]) or numpy.nansum( fluxpixels[rownum - 1, :]) == numpy.nan: message = 'ERROR -- KEPFIELD: Row ' + str( rownum) + ' is a bad quality timestamp' status = kepmsg.err(logfile, message, verbose) # construct input pixel image if status == 0: flux = fluxpixels[rownum - 1, :] ferr = errpixels[rownum - 1, :] DATx = arange(column, column + xdim) DATy = arange(row, row + ydim) # if numpy.nanmin > 420000.0: flux -= 420000.0 # image scale and intensity limits of pixel data if status == 0: n = 0 DATimg = empty((ydim, xdim)) ERRimg = empty((ydim, xdim)) for i in range(ydim): for j in range(xdim): DATimg[i, j] = flux[n] ERRimg[i, j] = ferr[n] n += 1 # determine suitable PRF calibration file if status == 0: if int(module) < 10: prefix = 'kplr0' else: prefix = 'kplr' prfglob = prfdir + '/' + prefix + str(module) + '.' + str( output) + '*' + '_prf.fits' try: prffile = glob.glob(prfglob)[0] except: message = 'ERROR -- KEPPRF: No PRF file found in ' + prfdir status = kepmsg.err(logfile, message, verbose) # read PRF images if status == 0: prfn = [0, 0, 0, 0, 0] crpix1p = numpy.zeros((5), dtype='float32') crpix2p = numpy.zeros((5), dtype='float32') crval1p = numpy.zeros((5), dtype='float32') crval2p = numpy.zeros((5), dtype='float32') cdelt1p = numpy.zeros((5), dtype='float32') cdelt2p = numpy.zeros((5), dtype='float32') for i in range(5): prfn[i], crpix1p[i], crpix2p[i], crval1p[i], crval2p[i], cdelt1p[i], cdelt2p[i], status \ = kepio.readPRFimage(prffile,i+1,logfile,verbose) prfn = array(prfn) PRFx = arange(0.5, shape(prfn[0])[1] + 0.5) PRFy = arange(0.5, shape(prfn[0])[0] + 0.5) PRFx = (PRFx - size(PRFx) / 2) * cdelt1p[0] PRFy = (PRFy - size(PRFy) / 2) * cdelt2p[0] # interpolate the calibrated PRF shape to the target position if status == 0: prf = zeros(shape(prfn[0]), dtype='float32') prfWeight = zeros((5), dtype='float32') for i in range(5): prfWeight[i] = sqrt((column - crval1p[i])**2 + (row - crval2p[i])**2) if prfWeight[i] == 0.0: prfWeight[i] = 1.0e-6 prf = prf + prfn[i] / prfWeight[i] prf = prf / nansum(prf) / cdelt1p[0] / cdelt2p[0] # interpolate the calibrated PRF shape to the target position # if status == 0: # prf = zeros(shape(prfn[0,:,:]),dtype='float32') # px = crval1p + len(PRFx) / 2 * cdelt1p[0] # py = crval2p + len(PRFy) / 2 * cdelt2p[0] # pp = [[px[0],py[0]], # [px[1],py[1]], # [px[2],py[2]], # [px[3],py[3]], # [px[4],py[4]]] # for index,value in ndenumerate(prf): # pz = prfn[:,index[0],index[1]] # prf[index] = griddata(pp, pz, ([column], [row]), method='linear') # print shape(prf) # location of the data image centered on the PRF image (in PRF pixel units) if status == 0: prfDimY = int(ydim / cdelt1p[0]) prfDimX = int(xdim / cdelt2p[0]) PRFy0 = (shape(prf)[0] - prfDimY) / 2 PRFx0 = (shape(prf)[1] - prfDimX) / 2 # interpolation function over the PRF if status == 0: splineInterpolation = scipy.interpolate.RectBivariateSpline( PRFx, PRFy, prf) # construct mesh for background model if status == 0 and background: bx = numpy.arange(1., float(xdim + 1)) by = numpy.arange(1., float(ydim + 1)) xx, yy = numpy.meshgrid(numpy.linspace(bx.min(), bx.max(), xdim), numpy.linspace(by.min(), by.max(), ydim)) # fit PRF model to pixel data if status == 0: start = time.time() if focus and background: args = (DATx, DATy, DATimg, ERRimg, nsrc, border, xx, yy, splineInterpolation, float(x[0]), float(y[0])) ans = fmin_powell(kepfunc.PRFwithFocusAndBackground, guess, args=args, xtol=xtol, ftol=ftol, disp=False) elif focus and not background: args = (DATx, DATy, DATimg, ERRimg, nsrc, splineInterpolation, float(x[0]), float(y[0])) ans = fmin_powell(kepfunc.PRFwithFocus, guess, args=args, xtol=xtol, ftol=ftol, disp=False) elif background and not focus: args = (DATx, DATy, DATimg, ERRimg, nsrc, border, xx, yy, splineInterpolation, float(x[0]), float(y[0])) ans = fmin_powell(kepfunc.PRFwithBackground, guess, args=args, xtol=xtol, ftol=ftol, disp=False) else: args = (DATx, DATy, DATimg, ERRimg, nsrc, splineInterpolation, float(x[0]), float(y[0])) ans = fmin_powell(kepfunc.PRF, guess, args=args, xtol=xtol, ftol=ftol, disp=False) print('Convergence time = %.2fs\n' % (time.time() - start)) # pad the PRF data if the PRF array is smaller than the data array if status == 0: flux = [] OBJx = [] OBJy = [] PRFmod = numpy.zeros((prfDimY, prfDimX)) if PRFy0 < 0 or PRFx0 < 0.0: PRFmod = numpy.zeros((prfDimY, prfDimX)) superPRF = zeros((prfDimY + 1, prfDimX + 1)) superPRF[abs(PRFy0):abs(PRFy0) + shape(prf)[0], abs(PRFx0):abs(PRFx0) + shape(prf)[1]] = prf prf = superPRF * 1.0 PRFy0 = 0 PRFx0 = 0 # rotate the PRF model around its center if focus: angle = ans[-1] prf = rotate(prf, -angle, reshape=False, mode='nearest') # iterate through the sources in the best fit PSF model for i in range(nsrc): flux.append(ans[i]) OBJx.append(ans[nsrc + i]) OBJy.append(ans[nsrc * 2 + i]) # calculate best-fit model y = (OBJy[i] - mean(DATy)) / cdelt1p[0] x = (OBJx[i] - mean(DATx)) / cdelt2p[0] prfTmp = shift(prf, [y, x], order=3, mode='constant') prfTmp = prfTmp[PRFy0:PRFy0 + prfDimY, PRFx0:PRFx0 + prfDimX] PRFmod = PRFmod + prfTmp * flux[i] wx = 1.0 wy = 1.0 angle = 0 b = 0.0 # write out best fit parameters if verbose: txt = 'Flux = %10.2f e-/s ' % flux[i] txt += 'X = %9.4f pix ' % OBJx[i] txt += 'Y = %9.4f pix ' % OBJy[i] kepmsg.log(logfile, txt, True) # # params = {'backend': 'png', # 'axes.linewidth': 2.5, # 'axes.labelsize': 24, # 'axes.font': 'sans-serif', # 'axes.fontweight' : 'bold', # 'text.fontsize': 12, # 'legend.fontsize': 12, # 'xtick.labelsize': 24, # 'ytick.labelsize': 24} # pylab.rcParams.update(params) # # pylab.figure(figsize=[20,10]) # ax = pylab.axes([0.05,0.08,0.46,0.9]) # xxx = numpy.arange(397.5,402.5,0.02) # yyy = numpy.sum(PRFmod,axis=0) / numpy.max(numpy.sum(PRFmod,axis=0)) # pylab.plot(xxx,yyy,color='b',linewidth=3.0) # xxx = numpy.append(numpy.insert(xxx,[0],[xxx[0]]),xxx[-1]) # yyy = numpy.append(numpy.insert(yyy,[0],[0.0]),yyy[-1]) # pylab.fill(xxx,yyy,fc='y',linewidth=0.0,alpha=0.3) # pylab.xlabel('Pixel Column Number') # pylab.xlim(397.5,402.5) # pylab.ylim(1.0e-30,1.02) # for xmaj in numpy.arange(397.5,402.5,1.0): # pylab.plot([xmaj,xmaj],[0.0,1.1],color='k',linewidth=0.5,linestyle=':') # for xmaj in numpy.arange(0.2,1.2,0.2): # pylab.plot([0.0,2000.0],[xmaj,xmaj],color='k',linewidth=0.5,linestyle=':') # # # ax = pylab.axes([0.51,0.08,0.46,0.9]) # xxx = numpy.arange(32.5,37.5,0.02) # yyy = numpy.sum(PRFmod,axis=1) / numpy.max(numpy.sum(PRFmod,axis=1)) # pylab.plot(xxx,yyy,color='b',linewidth=3.0) # xxx = numpy.append(numpy.insert(xxx,[0],[xxx[0]]),xxx[-1]) # yyy = numpy.append(numpy.insert(yyy,[0],[0.0]),yyy[-1]) # pylab.fill(xxx,yyy,fc='y',linewidth=0.0,alpha=0.3) # pylab.setp(pylab.gca(),yticklabels=[]) # pylab.xlabel('Pixel Row Number') # pylab.xlim(32.5,37.5) # pylab.ylim(1.0e-30,1.02) # for xmaj in numpy.arange(32.5,37.5,1.0): # pylab.plot([xmaj,xmaj],[0.0,1.1],color='k',linewidth=0.5,linestyle=':') # for xmaj in numpy.arange(0.2,1.2,0.2): # pylab.plot([0.0,2000.0],[xmaj,xmaj],color='k',linewidth=0.5,linestyle=':') # pylab.ion() # pylab.plot([]) # pylab.ioff() if verbose and background: bterms = border + 1 if bterms == 1: b = ans[nsrc * 3] else: bcoeff = array([ ans[nsrc * 3:nsrc * 3 + bterms], ans[nsrc * 3 + bterms:nsrc * 3 + bterms * 2] ]) bkg = kepfunc.polyval2d(xx, yy, bcoeff) b = nanmean(bkg.reshape(bkg.size)) txt = '\n Mean background = %.2f e-/s' % b kepmsg.log(logfile, txt, True) if focus: wx = ans[-3] wy = ans[-2] angle = ans[-1] if verbose and focus: if not background: kepmsg.log(logfile, '', True) kepmsg.log(logfile, ' X/Y focus factors = %.3f/%.3f' % (wx, wy), True) kepmsg.log(logfile, 'PRF rotation angle = %.2f deg' % angle, True) # measure flux fraction and contamination # LUGER: This looks horribly bugged. ``PRFall`` is certainly NOT the sum of the all the sources. if status == 0: PRFall = kepfunc.PRF2DET(flux, OBJx, OBJy, DATx, DATy, wx, wy, angle, splineInterpolation) PRFone = kepfunc.PRF2DET([flux[0]], [OBJx[0]], [OBJy[0]], DATx, DATy, wx, wy, angle, splineInterpolation) # LUGER: Add up contaminant fluxes PRFcont = np.zeros_like(PRFone) for ncont in range(1, len(flux)): PRFcont += kepfunc.PRF2DET([flux[ncont]], [OBJx[ncont]], [OBJy[ncont]], DATx, DATy, wx, wy, angle, splineInterpolation) PRFcont[np.where(PRFcont < 0)] = 0 FluxInMaskAll = numpy.nansum(PRFall) FluxInMaskOne = numpy.nansum(PRFone) FluxInAperAll = 0.0 FluxInAperOne = 0.0 FluxInAperAllTrue = 0.0 for i in range(1, ydim): for j in range(1, xdim): if kepstat.bitInBitmap(maskimg[i, j], 2): FluxInAperAll += PRFall[i, j] FluxInAperOne += PRFone[i, j] FluxInAperAllTrue += PRFone[i, j] + PRFcont[i, j] FluxFraction = FluxInAperOne / flux[0] try: Contamination = (FluxInAperAll - FluxInAperOne) / FluxInAperAll except: Contamination = 0.0 # LUGER: Pixel crowding metrics Crowding = PRFone / (PRFone + PRFcont) # LUGER: Optimal aperture crowding metric CrowdAper = FluxInAperOne / FluxInAperAllTrue kepmsg.log( logfile, '\n Total flux in mask = %.2f e-/s' % FluxInMaskAll, True) kepmsg.log( logfile, ' Target flux in mask = %.2f e-/s' % FluxInMaskOne, True) kepmsg.log( logfile, ' Total flux in aperture = %.2f e-/s' % FluxInAperAll, True) kepmsg.log( logfile, ' Target flux in aperture = %.2f e-/s' % FluxInAperOne, True) kepmsg.log( logfile, ' Target flux fraction in aperture = %.2f%%' % (FluxFraction * 100.0), True) kepmsg.log( logfile, 'Contamination fraction in aperture = %.2f%%' % (Contamination * 100.0), True) kepmsg.log(logfile, ' Crowding metric in aperture = %.4f' % (CrowdAper), True) # constuct model PRF in detector coordinates if status == 0: PRFfit = PRFall + 0.0 if background and bterms == 1: PRFfit = PRFall + b if background and bterms > 1: PRFfit = PRFall + bkg # calculate residual of DATA - FIT if status == 0: PRFres = DATimg - PRFfit FLUXres = numpy.nansum(PRFres) / npix # calculate the sum squared difference between data and model if status == 0: Pearson = abs(numpy.nansum(numpy.square(DATimg - PRFfit) / PRFfit)) Chi2 = numpy.nansum( numpy.square(DATimg - PRFfit) / numpy.square(ERRimg)) DegOfFreedom = npix - len(guess) - 1 try: kepmsg.log(logfile, '\n Residual flux = %.2f e-/s' % FLUXres, True) kepmsg.log( logfile, 'Pearson\'s chi^2 test = %d for %d dof' % (Pearson, DegOfFreedom), True) except: pass kepmsg.log( logfile, ' Chi^2 test = %d for %d dof' % (Chi2, DegOfFreedom), True) # image scale and intensity limits for plotting images if status == 0: imgdat_pl, zminfl, zmaxfl = kepplot.intScale2D(DATimg, imscale) imgprf_pl, zminpr, zmaxpr = kepplot.intScale2D(PRFmod, imscale) imgfit_pl, zminfi, zmaxfi = kepplot.intScale2D(PRFfit, imscale) imgres_pl, zminre, zmaxre = kepplot.intScale2D(PRFres, 'linear') if imscale == 'linear': zmaxpr *= 0.9 elif imscale == 'logarithmic': zmaxpr = numpy.max(zmaxpr) zminpr = zmaxpr / 2 # plot style if status == 0: pylab.figure(figsize=[12, 10]) pylab.clf() plotimage(imgdat_pl, zminfl, zmaxfl, 1, row, column, xdim, ydim, 0.07, 0.53, 'observation', colmap, labcol) # pylab.text(830.0,242.1,'A',horizontalalignment='center',verticalalignment='center', # fontsize=28,fontweight=500,color='white') # pylab.text(831.1,240.62,'B',horizontalalignment='center',verticalalignment='center', # fontsize=28,fontweight=500,color='white') # plotimage(imgprf_pl,0.0,zmaxpr/0.5,2,row,column,xdim,ydim,0.52,0.52,'model',colmap) plotimage(imgprf_pl, zminpr, zmaxpr, 2, row, column, xdim, ydim, 0.44, 0.53, 'model', colmap, labcol) kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 1, apercol, '--', 0.5) kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 2, apercol, '-', 3.0) plotimage(imgfit_pl, zminfl, zmaxfl, 3, row, column, xdim, ydim, 0.07, 0.08, 'fit', colmap, labcol, crowd=Crowding) # plotimage(imgres_pl,-zmaxre,zmaxre,4,row,column,xdim,ydim,0.44,0.08,'residual',colmap,'k') plotimage(imgres_pl, zminfl, zmaxfl, 4, row, column, xdim, ydim, 0.44, 0.08, 'residual', colmap, labcol) # plot data color bar # barwin = pylab.axes([0.84,0.53,0.06,0.45]) barwin = pylab.axes([0.84, 0.08, 0.06, 0.9]) if imscale == 'linear': brange = numpy.arange(zminfl, zmaxfl, (zmaxfl - zminfl) / 1000) elif imscale == 'logarithmic': brange = numpy.arange(10.0**zminfl, 10.0**zmaxfl, (10.0**zmaxfl - 10.0**zminfl) / 1000) elif imscale == 'squareroot': brange = numpy.arange(zminfl**2, zmaxfl**2, (zmaxfl**2 - zminfl**2) / 1000) if imscale == 'linear': barimg = numpy.resize(brange, (1000, 1)) elif imscale == 'logarithmic': barimg = numpy.log10(numpy.resize(brange, (1000, 1))) elif imscale == 'squareroot': barimg = numpy.sqrt(numpy.resize(brange, (1000, 1))) try: nrm = len(str(int(numpy.nanmax(brange)))) - 1 except: nrm = 0 brange = brange / 10**nrm pylab.imshow(barimg, aspect='auto', interpolation='nearest', origin='lower', vmin=numpy.nanmin(barimg), vmax=numpy.nanmax(barimg), extent=(0.0, 1.0, brange[0], brange[-1]), cmap=colmap) barwin.yaxis.tick_right() barwin.yaxis.set_label_position('right') barwin.yaxis.set_major_locator(MaxNLocator(7)) pylab.gca().yaxis.set_major_formatter( pylab.ScalarFormatter(useOffset=False)) pylab.gca().set_autoscale_on(False) pylab.setp(pylab.gca(), xticklabels=[], xticks=[]) pylab.ylabel('Flux (10$^%d$ e$^-$ s$^{-1}$)' % nrm) setp(barwin.get_yticklabels(), 'rotation', 90) barwin.yaxis.set_major_formatter(ticker.FormatStrFormatter('%.1f')) # plot residual color bar # barwin = pylab.axes([0.84,0.08,0.06,0.45]) # Brange = numpy.arange(-zmaxre,zmaxre,(zmaxre+zmaxre)/1000) # try: # nrm = len(str(int(numpy.nanmax(brange))))-1 # except: # nrm = 0 # brange = brange / 10**nrm # barimg = numpy.resize(brange,(1000,1)) # pylab.imshow(barimg,aspect='auto',interpolation='nearest',origin='lower', # vmin=brange[0],vmax=brange[-1],extent=(0.0,1.0,brange[0],brange[-1]),cmap=colmap) # barwin.yaxis.tick_right() # barwin.yaxis.set_label_position('right') # barwin.yaxis.set_major_formatter(ticker.FormatStrFormatter('%.1f')) # barwin.yaxis.set_major_locator(MaxNLocator(7)) # pylab.gca().yaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) # pylab.gca().set_autoscale_on(False) # pylab.setp(pylab.gca(),xticklabels=[],xticks=[]) # pylab.ylabel('Residual (10$^%d$ e$^-$ s$^{-1}$)' % nrm) # setp(barwin.get_yticklabels(), 'rotation', 90) # render plot if status == 0 and len(plotfile) > 0 and plotfile.lower() != 'none': pylab.savefig(plotfile) if status == 0 and plt: if cmdLine: pylab.show(block=True) else: pylab.ion() pylab.plot([]) pylab.ioff() # stop time kepmsg.clock('\nKEPPRF ended at', logfile, verbose) return
def kepprf(infile, plotfile, rownum, columns, rows, fluxes, border, background, focus, prfdir, xtol, ftol, imscale, colmap, plt, verbose, logfile, status, cmdLine=False): # input arguments print "... input arguments" status = 0 seterr(all="ignore") # log the call print "... logging the call" hashline = '----------------------------------------------------------------------------' kepmsg.log(logfile, hashline, verbose) call = 'KEPPRF -- ' call += 'infile=' + infile + ' ' call += 'plotfile=' + plotfile + ' ' call += 'rownum=' + str(rownum) + ' ' call += 'columns=' + columns + ' ' call += 'rows=' + rows + ' ' call += 'fluxes=' + fluxes + ' ' call += 'border=' + str(border) + ' ' bground = 'n' if (background): bground = 'y' call += 'background=' + bground + ' ' focs = 'n' if (focus): focs = 'y' call += 'focus=' + focs + ' ' call += 'prfdir=' + prfdir + ' ' call += 'xtol=' + str(xtol) + ' ' call += 'ftol=' + str(xtol) + ' ' call += 'imscale=' + imscale + ' ' call += 'colmap=' + colmap + ' ' plotit = 'n' if (plt): plotit = 'y' call += 'plot=' + plotit + ' ' chatter = 'n' if (verbose): chatter = 'y' call += 'verbose=' + chatter + ' ' call += 'logfile=' + logfile kepmsg.log(logfile, call + '\n', verbose) # test log file logfile = kepmsg.test(logfile) # start time print "... starting kepler time" kepmsg.clock('KEPPRF started at', logfile, verbose) # reference color map if colmap == 'browse': status = cmap_plot(cmdLine) # construct inital guess vector for fit print " status = " + str(status) print "... initial guess" if status == 0: guess = [] try: f = fluxes.strip().split(',') x = columns.strip().split(',') y = rows.strip().split(',') for i in xrange(len(f)): f[i] = float(f[i]) except: f = fluxes x = columns y = rows nsrc = len(f) for i in xrange(nsrc): try: guess.append(float(f[i])) except: message = 'ERROR -- KEPPRF: Fluxes must be floating point numbers' status = kepmsg.err(logfile, message, verbose) if status == 0: if len(x) != nsrc or len(y) != nsrc: message = 'ERROR -- KEPFIT:FITMULTIPRF: Guesses for rows, columns and ' message += 'fluxes must have the same number of sources' status = kepmsg.err(logfile, message, verbose) if status == 0: for i in xrange(nsrc): try: guess.append(float(x[i])) except: message = 'ERROR -- KEPPRF: Columns must be floating point numbers' status = kepmsg.err(logfile, message, verbose) if status == 0: for i in xrange(nsrc): try: guess.append(float(y[i])) except: message = 'ERROR -- KEPPRF: Rows must be floating point numbers' status = kepmsg.err(logfile, message, verbose) if status == 0 and background: if border == 0: guess.append(0.0) else: for i in range((border + 1) * 2): guess.append(0.0) if status == 0 and focus: guess.append(1.0) guess.append(1.0) guess.append(0.0) # open TPF FITS file print "... open tpf file" if status == 0: try: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, barytime, status = \ kepio.readTPF(infile,'TIME',logfile,verbose) except: message = 'ERROR -- KEPPRF: is %s a Target Pixel File? ' % infile status = kepmsg.err(logfile, message, verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, tcorr, status = \ kepio.readTPF(infile,'TIMECORR',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, cadno, status = \ kepio.readTPF(infile,'CADENCENO',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, fluxpixels, status = \ kepio.readTPF(infile,'FLUX',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, errpixels, status = \ kepio.readTPF(infile,'FLUX_ERR',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, qual, status = \ kepio.readTPF(infile,'QUALITY',logfile,verbose) # read mask defintion data from TPF file print "... read mask definition" if status == 0: maskimg, pixcoord1, pixcoord2, status = kepio.readMaskDefinition( infile, logfile, verbose) npix = numpy.size(numpy.nonzero(maskimg)[0]) # print target data if status == 0 and verbose: print '' print ' KepID: %s' % kepid print ' RA (J2000): %s' % ra print 'Dec (J2000): %s' % dec print ' KepMag: %s' % kepmag print ' SkyGroup: %2s' % skygroup print ' Season: %2s' % str(season) print ' Channel: %2s' % channel print ' Module: %2s' % module print ' Output: %1s' % output print '' # is this a good row with finite timestamp and pixels? if status == 0: if not numpy.isfinite(barytime[rownum - 1]) or numpy.nansum( fluxpixels[rownum - 1, :]) == numpy.nan: message = 'ERROR -- KEPFIELD: Row ' + str( rownum) + ' is a bad quality timestamp' status = kepmsg.err(logfile, message, verbose) # construct input pixel image if status == 0: flux = fluxpixels[rownum - 1, :] ferr = errpixels[rownum - 1, :] DATx = arange(column, column + xdim) DATy = arange(row, row + ydim) # image scale and intensity limits of pixel data if status == 0: n = 0 DATimg = empty((ydim, xdim)) ERRimg = empty((ydim, xdim)) for i in range(ydim): for j in range(xdim): DATimg[i, j] = flux[n] ERRimg[i, j] = ferr[n] n += 1 # determine suitable PRF calibration file if status == 0: if int(module) < 10: prefix = 'kplr0' else: prefix = 'kplr' prfglob = prfdir + '/' + prefix + str(module) + '.' + str( output) + '*' + '_prf.fits' try: prffile = glob.glob(prfglob)[0] except: message = 'ERROR -- KEPPRF: No PRF file found in ' + prfdir status = kepmsg.err(logfile, message, verbose) # read PRF images if status == 0: prfn = [0, 0, 0, 0, 0] crpix1p = numpy.zeros((5), dtype='float32') crpix2p = numpy.zeros((5), dtype='float32') crval1p = numpy.zeros((5), dtype='float32') crval2p = numpy.zeros((5), dtype='float32') cdelt1p = numpy.zeros((5), dtype='float32') cdelt2p = numpy.zeros((5), dtype='float32') for i in range(5): prfn[i], crpix1p[i], crpix2p[i], crval1p[i], crval2p[i], cdelt1p[i], cdelt2p[i], status \ = kepio.readPRFimage(prffile,i+1,logfile,verbose) PRFx = arange(0.5, shape(prfn[0])[1] + 0.5) PRFy = arange(0.5, shape(prfn[0])[0] + 0.5) PRFx = (PRFx - size(PRFx) / 2) * cdelt1p[0] PRFy = (PRFy - size(PRFy) / 2) * cdelt2p[0] # interpolate the calibrated PRF shape to the target position if status == 0: prf = zeros(shape(prfn[0]), dtype='float32') prfWeight = zeros((5), dtype='float32') for i in xrange(5): prfWeight[i] = sqrt((column - crval1p[i])**2 + (row - crval2p[i])**2) if prfWeight[i] == 0.0: prfWeight[i] = 1.0e6 prf = prf + prfn[i] / prfWeight[i] prf = prf / nansum(prf) prf = prf / cdelt1p[0] / cdelt2p[0] # location of the data image centered on the PRF image (in PRF pixel units) if status == 0: prfDimY = int(ydim / cdelt1p[0]) prfDimX = int(xdim / cdelt2p[0]) PRFy0 = (shape(prf)[0] - prfDimY) / 2 PRFx0 = (shape(prf)[1] - prfDimX) / 2 # interpolation function over the PRF if status == 0: splineInterpolation = scipy.interpolate.RectBivariateSpline( PRFx, PRFy, prf) # construct mesh for background model if status == 0 and background: bx = numpy.arange(1., float(xdim + 1)) by = numpy.arange(1., float(ydim + 1)) xx, yy = numpy.meshgrid(numpy.linspace(bx.min(), bx.max(), xdim), numpy.linspace(by.min(), by.max(), ydim)) # fit PRF model to pixel data if status == 0: start = time.time() if focus and background: args = (DATx, DATy, DATimg, nsrc, border, xx, yy, PRFx, PRFy, splineInterpolation) ans = fmin_powell(kepfunc.PRFwithFocusAndBackground, guess, args=args, xtol=xtol, ftol=ftol, disp=False) elif focus and not background: args = (DATx, DATy, DATimg, nsrc, PRFx, PRFy, splineInterpolation) ans = fmin_powell(kepfunc.PRFwithFocus, guess, args=args, xtol=xtol, ftol=ftol, disp=False) elif background and not focus: args = (DATx, DATy, DATimg, nsrc, border, xx, yy, splineInterpolation) ans = fmin_powell(kepfunc.PRFwithBackground, guess, args=args, xtol=xtol, ftol=ftol, disp=False) else: args = (DATx, DATy, DATimg, splineInterpolation) ans = fmin_powell(kepfunc.PRF, guess, args=args, xtol=xtol, ftol=ftol, disp=False) print 'Convergence time = %.2fs\n' % (time.time() - start) # pad the PRF data if the PRF array is smaller than the data array if status == 0: flux = [] OBJx = [] OBJy = [] PRFmod = numpy.zeros((prfDimY, prfDimX)) if PRFy0 < 0 or PRFx0 < 0.0: PRFmod = numpy.zeros((prfDimY, prfDimX)) superPRF = zeros((prfDimY + 1, prfDimX + 1)) superPRF[abs(PRFy0):abs(PRFy0) + shape(prf)[0], abs(PRFx0):abs(PRFx0) + shape(prf)[1]] = prf prf = superPRF * 1.0 PRFy0 = 0 PRFx0 = 0 # rotate the PRF model around its center if focus: angle = ans[-1] prf = rotate(prf, -angle, reshape=False, mode='nearest') # iterate through the sources in the best fit PSF model for i in range(nsrc): flux.append(ans[i]) OBJx.append(ans[nsrc + i]) OBJy.append(ans[nsrc * 2 + i]) # calculate best-fit model y = (OBJy[i] - mean(DATy)) / cdelt1p[0] x = (OBJx[i] - mean(DATx)) / cdelt2p[0] prfTmp = shift(prf, [y, x], order=1, mode='constant') prfTmp = prfTmp[PRFy0:PRFy0 + prfDimY, PRFx0:PRFx0 + prfDimX] PRFmod = PRFmod + prfTmp * flux[i] wx = 1.0 wy = 1.0 angle = 0 b = 0.0 # write out best fit parameters if verbose: txt = 'Flux = %10.2f e-/s ' % flux[i] txt += 'X = %9.4f pix ' % OBJx[i] txt += 'Y = %9.4f pix ' % OBJy[i] kepmsg.log(logfile, txt, True) if verbose and background: bterms = border + 1 if bterms == 1: b = ans[nsrc * 3] else: bcoeff = array([ ans[nsrc * 3:nsrc * 3 + bterms], ans[nsrc * 3 + bterms:nsrc * 3 + bterms * 2] ]) bkg = kepfunc.polyval2d(xx, yy, bcoeff) b = nanmean(bkg.reshape(bkg.size)) txt = '\n Mean background = %.2f e-/s' % b kepmsg.log(logfile, txt, True) if focus: wx = ans[-3] wy = ans[-2] angle = ans[-1] if verbose and focus: if not background: kepmsg.log(logfile, '', True) kepmsg.log(logfile, ' X/Y focus factors = %.3f/%.3f' % (wx, wy), True) kepmsg.log(logfile, 'PRF rotation angle = %.2f deg' % angle, True) # constuct model PRF in detector coordinates if status == 0: PRFfit = kepfunc.PRF2DET(flux, OBJx, OBJy, DATx, DATy, wx, wy, angle, splineInterpolation) if background and bterms == 1: PRFfit = PRFfit + b if background and bterms > 1: PRFfit = PRFfit + bkg # calculate residual of DATA - FIT if status == 0: PRFres = DATimg - PRFfit FLUXres = numpy.nansum(PRFres) # calculate the sum squared difference between data and model if status == 0: Pearson = abs(numpy.nansum(numpy.square(DATimg - PRFfit) / PRFfit)) Chi2 = numpy.nansum( numpy.square(DATimg - PRFfit) / numpy.square(ERRimg)) DegOfFreedom = npix - len(guess) try: kepmsg.log(logfile, '\nResidual flux = %.6f e-/s' % FLUXres, True) kepmsg.log( logfile, 'Pearson\'s chi^2 test = %d for %d dof' % (Pearson, DegOfFreedom), True) except: pass # kepmsg.log(logfile,'Chi^2 test = %d for %d dof' % (Chi2,DegOfFreedom),True) # image scale and intensity limits for plotting images if status == 0: imgdat_pl, zminfl, zmaxfl = kepplot.intScale2D(DATimg, imscale) imgprf_pl, zminpr, zmaxpr = kepplot.intScale2D(PRFmod, imscale) imgfit_pl, zminfi, zmaxfi = kepplot.intScale2D(PRFfit, imscale) imgres_pl, zminre, zmaxre = kepplot.intScale2D(PRFres, imscale) if imscale == 'linear': zmaxpr *= 0.9 elif imscale == 'logarithmic': print zminpr, zmaxpr, numpy.max(zmaxpr) zmaxpr = numpy.max(zmaxpr) zminpr = zmaxpr / 2 # plot style if status == 0: try: params = { 'backend': 'png', 'axes.linewidth': 2.5, 'axes.labelsize': 24, 'axes.font': 'sans-serif', 'axes.fontweight': 'bold', 'text.fontsize': 12, 'legend.fontsize': 12, 'xtick.labelsize': 10, 'ytick.labelsize': 10 } pylab.rcParams.update(params) except: pass pylab.figure(figsize=[10, 10]) pylab.clf() plotimage(imgdat_pl, zminfl, zmaxfl, 1, row, column, xdim, ydim, 0.06, 0.52, 'flux', colmap) plotimage(imgprf_pl, zminpr, zmaxpr, 2, row, column, xdim, ydim, 0.52, 0.52, 'model', colmap) kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 1, 'b', '--', 0.5) kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 2, 'b', '-', 3.0) plotimage(imgfit_pl, zminfl, zmaxfl, 3, row, column, xdim, ydim, 0.06, 0.06, 'fit', colmap) plotimage(imgres_pl, zminfl, zmaxfl, 4, row, column, xdim, ydim, 0.52, 0.06, 'residual', colmap) # render plot if status == 0 and len(plotfile) > 0 and plotfile.lower() != 'none': pylab.savefig(plotfile) if status == 0 and plt: if cmdLine: pylab.show(block=True) else: pylab.ion() pylab.plot([]) pylab.ioff() # stop time kepmsg.clock('\nKEPPRF ended at', logfile, verbose) return
def kepprfphot(infile,outroot,columns,rows,fluxes,border,background,focus,prfdir,ranges, tolerance,ftolerance,qualflags,plt,clobber,verbose,logfile,status,cmdLine=False): # input arguments status = 0 seterr(all="ignore") # log the call hashline = '----------------------------------------------------------------------------' kepmsg.log(logfile,hashline,verbose) call = 'KEPPRFPHOT -- ' call += 'infile='+infile+' ' call += 'outroot='+outroot+' ' call += 'columns='+columns+' ' call += 'rows='+rows+' ' call += 'fluxes='+fluxes+' ' call += 'border='+str(border)+' ' bground = 'n' if (background): bground = 'y' call += 'background='+bground+' ' focs = 'n' if (focus): focs = 'y' call += 'focus='+focs+' ' call += 'prfdir='+prfdir+' ' call += 'ranges='+ranges+' ' call += 'xtol='+str(tolerance)+' ' call += 'ftol='+str(ftolerance)+' ' quality = 'n' if (qualflags): quality = 'y' call += 'qualflags='+quality+' ' plotit = 'n' if (plt): plotit = 'y' call += 'plot='+plotit+' ' overwrite = 'n' if (clobber): overwrite = 'y' call += 'clobber='+overwrite+ ' ' chatter = 'n' if (verbose): chatter = 'y' call += 'verbose='+chatter+' ' call += 'logfile='+logfile kepmsg.log(logfile,call+'\n',verbose) # test log file logfile = kepmsg.test(logfile) # start time kepmsg.clock('KEPPRFPHOT started at',logfile,verbose) # number of sources if status == 0: work = fluxes.strip() work = re.sub(' ',',',work) work = re.sub(';',',',work) nsrc = len(work.split(',')) # construct inital guess vector for fit if status == 0: guess = [] try: f = fluxes.strip().split(',') x = columns.strip().split(',') y = rows.strip().split(',') for i in xrange(len(f)): f[i] = float(f[i]) except: f = fluxes x = columns y = rows nsrc = len(f) for i in xrange(nsrc): try: guess.append(float(f[i])) except: message = 'ERROR -- KEPPRF: Fluxes must be floating point numbers' status = kepmsg.err(logfile,message,verbose) if status == 0: if len(x) != nsrc or len(y) != nsrc: message = 'ERROR -- KEPFIT:FITMULTIPRF: Guesses for rows, columns and ' message += 'fluxes must have the same number of sources' status = kepmsg.err(logfile,message,verbose) if status == 0: for i in xrange(nsrc): try: guess.append(float(x[i])) except: message = 'ERROR -- KEPPRF: Columns must be floating point numbers' status = kepmsg.err(logfile,message,verbose) if status == 0: for i in xrange(nsrc): try: guess.append(float(y[i])) except: message = 'ERROR -- KEPPRF: Rows must be floating point numbers' status = kepmsg.err(logfile,message,verbose) if status == 0 and background: if border == 0: guess.append(0.0) else: for i in range((border+1)*2): guess.append(0.0) if status == 0 and focus: guess.append(1.0); guess.append(1.0); guess.append(0.0) # clobber output file for i in range(nsrc): outfile = '%s_%d.fits' % (outroot, i) if clobber: status = kepio.clobber(outfile,logfile,verbose) if kepio.fileexists(outfile): message = 'ERROR -- KEPPRFPHOT: ' + outfile + ' exists. Use --clobber' status = kepmsg.err(logfile,message,verbose) # open TPF FITS file if status == 0: try: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, barytime, status = \ kepio.readTPF(infile,'TIME',logfile,verbose) except: message = 'ERROR -- KEPPRFPHOT: is %s a Target Pixel File? ' % infile status = kepmsg.err(logfile,message,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, tcorr, status = \ kepio.readTPF(infile,'TIMECORR',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, cadno, status = \ kepio.readTPF(infile,'CADENCENO',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, fluxpixels, status = \ kepio.readTPF(infile,'FLUX',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, errpixels, status = \ kepio.readTPF(infile,'FLUX_ERR',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, poscorr1, status = \ kepio.readTPF(infile,'POS_CORR1',logfile,verbose) if status != 0: poscorr1 = numpy.zeros((len(barytime)),dtype='float32') poscorr1[:] = numpy.nan status = 0 if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, poscorr2, status = \ kepio.readTPF(infile,'POS_CORR2',logfile,verbose) if status != 0: poscorr2 = numpy.zeros((len(barytime)),dtype='float32') poscorr2[:] = numpy.nan status = 0 if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, qual, status = \ kepio.readTPF(infile,'QUALITY',logfile,verbose) if status == 0: struct, status = kepio.openfits(infile,'readonly',logfile,verbose) if status == 0: tstart, tstop, bjdref, cadence, status = kepio.timekeys(struct,infile,logfile,verbose,status) # input file keywords and mask map if status == 0: cards0 = struct[0].header.cards cards1 = struct[1].header.cards cards2 = struct[2].header.cards maskmap = copy(struct[2].data) npix = numpy.size(numpy.nonzero(maskmap)[0]) # print target data if status == 0 and verbose: print '' print ' KepID: %s' % kepid print ' RA (J2000): %s' % ra print 'Dec (J2000): %s' % dec print ' KepMag: %s' % kepmag print ' SkyGroup: %2s' % skygroup print ' Season: %2s' % str(season) print ' Channel: %2s' % channel print ' Module: %2s' % module print ' Output: %1s' % output print '' # determine suitable PRF calibration file if status == 0: if int(module) < 10: prefix = 'kplr0' else: prefix = 'kplr' prfglob = prfdir + '/' + prefix + str(module) + '.' + str(output) + '*' + '_prf.fits' try: prffile = glob.glob(prfglob)[0] except: message = 'ERROR -- KEPPRFPHOT: No PRF file found in ' + prfdir status = kepmsg.err(logfile,message,verbose) # read PRF images if status == 0: prfn = [0,0,0,0,0] crpix1p = numpy.zeros((5),dtype='float32') crpix2p = numpy.zeros((5),dtype='float32') crval1p = numpy.zeros((5),dtype='float32') crval2p = numpy.zeros((5),dtype='float32') cdelt1p = numpy.zeros((5),dtype='float32') cdelt2p = numpy.zeros((5),dtype='float32') for i in range(5): prfn[i], crpix1p[i], crpix2p[i], crval1p[i], crval2p[i], cdelt1p[i], cdelt2p[i], status \ = kepio.readPRFimage(prffile,i+1,logfile,verbose) PRFx = arange(0.5,shape(prfn[0])[1]+0.5) PRFy = arange(0.5,shape(prfn[0])[0]+0.5) PRFx = (PRFx - size(PRFx) / 2) * cdelt1p[0] PRFy = (PRFy - size(PRFy) / 2) * cdelt2p[0] # interpolate the calibrated PRF shape to the target position if status == 0: prf = zeros(shape(prfn[0]),dtype='float32') prfWeight = zeros((5),dtype='float32') for i in xrange(5): prfWeight[i] = sqrt((column - crval1p[i])**2 + (row - crval2p[i])**2) if prfWeight[i] == 0.0: prfWeight[i] = 1.0e6 prf = prf + prfn[i] / prfWeight[i] prf = prf / nansum(prf) prf = prf / cdelt1p[0] / cdelt2p[0] # location of the data image centered on the PRF image (in PRF pixel units) if status == 0: prfDimY = ydim / cdelt1p[0] prfDimX = xdim / cdelt2p[0] PRFy0 = (shape(prf)[0] - prfDimY) / 2 PRFx0 = (shape(prf)[1] - prfDimX) / 2 # construct input pixel image if status == 0: DATx = arange(column,column+xdim) DATy = arange(row,row+ydim) # interpolation function over the PRF if status == 0: splineInterpolation = scipy.interpolate.RectBivariateSpline(PRFx,PRFy,prf,kx=3,ky=3) # construct mesh for background model if status == 0: bx = numpy.arange(1.,float(xdim+1)) by = numpy.arange(1.,float(ydim+1)) xx, yy = numpy.meshgrid(numpy.linspace(bx.min(), bx.max(), xdim), numpy.linspace(by.min(), by.max(), ydim)) # Get time ranges for new photometry, flag good data if status == 0: barytime += bjdref tstart,tstop,status = kepio.timeranges(ranges,logfile,verbose) incl = numpy.zeros((len(barytime)),dtype='int') for rownum in xrange(len(barytime)): for winnum in xrange(len(tstart)): if barytime[rownum] >= tstart[winnum] and \ barytime[rownum] <= tstop[winnum] and \ (qual[rownum] == 0 or qualflags) and \ numpy.isfinite(barytime[rownum]) and \ numpy.isfinite(numpy.nansum(fluxpixels[rownum,:])): incl[rownum] = 1 if not numpy.in1d(1,incl): message = 'ERROR -- KEPPRFPHOT: No legal data within the range ' + ranges status = kepmsg.err(logfile,message,verbose) # filter out bad data if status == 0: n = 0 nincl = (incl == 1).sum() tim = zeros((nincl),'float64') tco = zeros((nincl),'float32') cad = zeros((nincl),'float32') flu = zeros((nincl,len(fluxpixels[0])),'float32') fer = zeros((nincl,len(fluxpixels[0])),'float32') pc1 = zeros((nincl),'float32') pc2 = zeros((nincl),'float32') qua = zeros((nincl),'float32') for rownum in xrange(len(barytime)): if incl[rownum] == 1: tim[n] = barytime[rownum] tco[n] = tcorr[rownum] cad[n] = cadno[rownum] flu[n,:] = fluxpixels[rownum] fer[n,:] = errpixels[rownum] pc1[n] = poscorr1[rownum] pc2[n] = poscorr2[rownum] qua[n] = qual[rownum] n += 1 barytime = tim * 1.0 tcorr = tco * 1.0 cadno = cad * 1.0 fluxpixels = flu * 1.0 errpixels = fer * 1.0 poscorr1 = pc1 * 1.0 poscorr2 = pc2 * 1.0 qual = qua * 1.0 # initialize plot arrays if status == 0: t = numpy.array([],dtype='float64') fl = []; dx = []; dy = []; bg = []; fx = []; fy = []; fa = []; rs = []; ch = [] for i in range(nsrc): fl.append(numpy.array([],dtype='float32')) dx.append(numpy.array([],dtype='float32')) dy.append(numpy.array([],dtype='float32')) # Preparing fit data message if status == 0: progress = numpy.arange(nincl) if verbose: txt = 'Preparing...' sys.stdout.write(txt) sys.stdout.flush() # single processor version if status == 0:# and not cmdLine: oldtime = 0.0 for rownum in xrange(numpy.min([80,len(barytime)])): try: if barytime[rownum] - oldtime > 0.5: ftol = 1.0e-10; xtol = 1.0e-10 except: pass args = (fluxpixels[rownum,:],errpixels[rownum,:],DATx,DATy,nsrc,border,xx,yy,PRFx,PRFy,splineInterpolation, guess,ftol,xtol,focus,background,rownum,80,float(x[i]),float(y[i]),False) guess = PRFfits(args) ftol = ftolerance; xtol = tolerance; oldtime = barytime[rownum] # Fit the time series: multi-processing if status == 0 and cmdLine: anslist = [] cad1 = 0; cad2 = 50 for i in range(int(nincl/50) + 1): try: fluxp = fluxpixels[cad1:cad2,:] errp = errpixels[cad1:cad2,:] progress = numpy.arange(cad1,cad2) except: fluxp = fluxpixels[cad1:nincl,:] errp = errpixels[cad1:nincl,:] progress = numpy.arange(cad1,nincl) try: args = itertools.izip(fluxp,errp,itertools.repeat(DATx),itertools.repeat(DATy), itertools.repeat(nsrc),itertools.repeat(border),itertools.repeat(xx), itertools.repeat(yy),itertools.repeat(PRFx),itertools.repeat(PRFy), itertools.repeat(splineInterpolation),itertools.repeat(guess), itertools.repeat(ftolerance),itertools.repeat(tolerance), itertools.repeat(focus),itertools.repeat(background),progress, itertools.repeat(numpy.arange(cad1,nincl)[-1]), itertools.repeat(float(x[0])), itertools.repeat(float(y[0])),itertools.repeat(True)) p = multiprocessing.Pool() model = [0.0] model = p.imap(PRFfits,args,chunksize=1) p.close() p.join() cad1 += 50; cad2 += 50 ans = array([array(item) for item in zip(*model)]) try: anslist = numpy.concatenate((anslist,ans.transpose()),axis=0) except: anslist = ans.transpose() guess = anslist[-1] ans = anslist.transpose() except: pass # single processor version if status == 0 and not cmdLine: oldtime = 0.0; ans = [] # for rownum in xrange(1,10): for rownum in xrange(nincl): proctime = time.time() try: if barytime[rownum] - oldtime > 0.5: ftol = 1.0e-10; xtol = 1.0e-10 except: pass args = (fluxpixels[rownum,:],errpixels[rownum,:],DATx,DATy,nsrc,border,xx,yy,PRFx,PRFy,splineInterpolation, guess,ftol,xtol,focus,background,rownum,nincl,float(x[0]),float(y[0]),True) guess = PRFfits(args) ans.append(guess) ftol = ftolerance; xtol = tolerance; oldtime = barytime[rownum] ans = array(ans).transpose() # unpack the best fit parameters if status == 0: flux = []; OBJx = []; OBJy = [] na = shape(ans)[1] for i in range(nsrc): flux.append(ans[i,:]) OBJx.append(ans[nsrc+i,:]) OBJy.append(ans[nsrc*2+i,:]) try: bterms = border + 1 if bterms == 1: b = ans[nsrc*3,:] else: b = array([]) bkg = [] for i in range(na): bcoeff = array([ans[nsrc*3:nsrc*3+bterms,i],ans[nsrc*3+bterms:nsrc*3+bterms*2,i]]) bkg.append(kepfunc.polyval2d(xx,yy,bcoeff)) b = numpy.append(b,nanmean(bkg[-1].reshape(bkg[-1].size))) except: b = zeros((na)) if focus: wx = ans[-3,:]; wy = ans[-2,:]; angle = ans[-1,:] else: wx = ones((na)); wy = ones((na)); angle = zeros((na)) # constuct model PRF in detector coordinates if status == 0: residual = []; chi2 = [] for i in range(na): f = empty((nsrc)) x = empty((nsrc)) y = empty((nsrc)) for j in range(nsrc): f[j] = flux[j][i] x[j] = OBJx[j][i] y[j] = OBJy[j][i] PRFfit = kepfunc.PRF2DET(f,x,y,DATx,DATy,wx[i],wy[i],angle[i],splineInterpolation) if background and bterms == 1: PRFfit = PRFfit + b[i] if background and bterms > 1: PRFfit = PRFfit + bkg[i] # calculate residual of DATA - FIT xdim = shape(xx)[1] ydim = shape(yy)[0] DATimg = numpy.empty((ydim,xdim)) n = 0 for k in range(ydim): for j in range(xdim): DATimg[k,j] = fluxpixels[i,n] n += 1 PRFres = DATimg - PRFfit residual.append(numpy.nansum(PRFres) / npix) # calculate the sum squared difference between data and model chi2.append(abs(numpy.nansum(numpy.square(DATimg - PRFfit) / PRFfit))) # load the output arrays if status == 0: otime = barytime - bjdref otimecorr = tcorr ocadenceno = cadno opos_corr1 = poscorr1 opos_corr2 = poscorr2 oquality = qual opsf_bkg = b opsf_focus1 = wx opsf_focus2 = wy opsf_rotation = angle opsf_residual = residual opsf_chi2 = chi2 opsf_flux_err = numpy.empty((na)); opsf_flux_err.fill(numpy.nan) opsf_centr1_err = numpy.empty((na)); opsf_centr1_err.fill(numpy.nan) opsf_centr2_err = numpy.empty((na)); opsf_centr2_err.fill(numpy.nan) opsf_bkg_err = numpy.empty((na)); opsf_bkg_err.fill(numpy.nan) opsf_flux = [] opsf_centr1 = [] opsf_centr2 = [] for i in range(nsrc): opsf_flux.append(flux[i]) opsf_centr1.append(OBJx[i]) opsf_centr2.append(OBJy[i]) # load the plot arrays if status == 0: t = barytime for i in range(nsrc): fl[i] = flux[i] dx[i] = OBJx[i] dy[i] = OBJy[i] bg = b fx = wx fy = wy fa = angle rs = residual ch = chi2 # construct output primary extension if status == 0: for j in range(nsrc): hdu0 = pyfits.PrimaryHDU() for i in range(len(cards0)): if cards0[i].key not in hdu0.header.keys(): hdu0.header.update(cards0[i].key, cards0[i].value, cards0[i].comment) else: hdu0.header.cards[cards0[i].key].comment = cards0[i].comment status = kepkey.history(call,hdu0,outfile,logfile,verbose) outstr = HDUList(hdu0) # construct output light curve extension col1 = Column(name='TIME',format='D',unit='BJD - 2454833',array=otime) col2 = Column(name='TIMECORR',format='E',unit='d',array=otimecorr) col3 = Column(name='CADENCENO',format='J',array=ocadenceno) col4 = Column(name='PSF_FLUX',format='E',unit='e-/s',array=opsf_flux[j]) col5 = Column(name='PSF_FLUX_ERR',format='E',unit='e-/s',array=opsf_flux_err) col6 = Column(name='PSF_BKG',format='E',unit='e-/s/pix',array=opsf_bkg) col7 = Column(name='PSF_BKG_ERR',format='E',unit='e-/s',array=opsf_bkg_err) col8 = Column(name='PSF_CENTR1',format='E',unit='pixel',array=opsf_centr1[j]) col9 = Column(name='PSF_CENTR1_ERR',format='E',unit='pixel',array=opsf_centr1_err) col10 = Column(name='PSF_CENTR2',format='E',unit='pixel',array=opsf_centr2[j]) col11 = Column(name='PSF_CENTR2_ERR',format='E',unit='pixel',array=opsf_centr2_err) col12 = Column(name='PSF_FOCUS1',format='E',array=opsf_focus1) col13 = Column(name='PSF_FOCUS2',format='E',array=opsf_focus2) col14 = Column(name='PSF_ROTATION',format='E',unit='deg',array=opsf_rotation) col15 = Column(name='PSF_RESIDUAL',format='E',unit='e-/s',array=opsf_residual) col16 = Column(name='PSF_CHI2',format='E',array=opsf_chi2) col17 = Column(name='POS_CORR1',format='E',unit='pixel',array=opos_corr1) col18 = Column(name='POS_CORR2',format='E',unit='pixel',array=opos_corr2) col19 = Column(name='SAP_QUALITY',format='J',array=oquality) cols = ColDefs([col1,col2,col3,col4,col5,col6,col7,col8,col9,col10,col11, col12,col13,col14,col15,col16,col17,col18,col19]) hdu1 = new_table(cols) for i in range(len(cards1)): if (cards1[i].key not in hdu1.header.keys() and cards1[i].key[:4] not in ['TTYP','TFOR','TUNI','TDIS','TDIM','WCAX','1CTY', '2CTY','1CRP','2CRP','1CRV','2CRV','1CUN','2CUN', '1CDE','2CDE','1CTY','2CTY','1CDL','2CDL','11PC', '12PC','21PC','22PC']): hdu1.header.update(cards1[i].key, cards1[i].value, cards1[i].comment) outstr.append(hdu1) # construct output mask bitmap extension hdu2 = ImageHDU(maskmap) for i in range(len(cards2)): if cards2[i].key not in hdu2.header.keys(): hdu2.header.update(cards2[i].key, cards2[i].value, cards2[i].comment) else: hdu2.header.cards[cards2[i].key].comment = cards2[i].comment outstr.append(hdu2) # write output file outstr.writeto(outroot + '_' + str(j) + '.fits',checksum=True) # close input structure status = kepio.closefits(struct,logfile,verbose) # clean up x-axis unit if status == 0: barytime0 = float(int(t[0] / 100) * 100.0) t -= barytime0 t = numpy.insert(t,[0],[t[0]]) t = numpy.append(t,[t[-1]]) xlab = 'BJD $-$ %d' % barytime0 # plot the light curves if status == 0: bg = numpy.insert(bg,[0],[-1.0e10]) bg = numpy.append(bg,-1.0e10) fx = numpy.insert(fx,[0],[fx[0]]) fx = numpy.append(fx,fx[-1]) fy = numpy.insert(fy,[0],[fy[0]]) fy = numpy.append(fy,fy[-1]) fa = numpy.insert(fa,[0],[fa[0]]) fa = numpy.append(fa,fa[-1]) rs = numpy.insert(rs,[0],[-1.0e10]) rs = numpy.append(rs,-1.0e10) ch = numpy.insert(ch,[0],[-1.0e10]) ch = numpy.append(ch,-1.0e10) for i in range(nsrc): # clean up y-axis units nrm = math.ceil(math.log10(numpy.nanmax(fl[i]))) - 1.0 fl[i] /= 10**nrm if nrm == 0: ylab1 = 'e$^-$ s$^{-1}$' else: ylab1 = '10$^{%d}$ e$^-$ s$^{-1}$' % nrm xx = copy(dx[i]) yy = copy(dy[i]) ylab2 = 'offset (pixels)' # data limits xmin = numpy.nanmin(t) xmax = numpy.nanmax(t) ymin1 = numpy.nanmin(fl[i]) ymax1 = numpy.nanmax(fl[i]) ymin2 = numpy.nanmin(xx) ymax2 = numpy.nanmax(xx) ymin3 = numpy.nanmin(yy) ymax3 = numpy.nanmax(yy) ymin4 = numpy.nanmin(bg[1:-1]) ymax4 = numpy.nanmax(bg[1:-1]) ymin5 = numpy.nanmin([numpy.nanmin(fx),numpy.nanmin(fy)]) ymax5 = numpy.nanmax([numpy.nanmax(fx),numpy.nanmax(fy)]) ymin6 = numpy.nanmin(fa[1:-1]) ymax6 = numpy.nanmax(fa[1:-1]) ymin7 = numpy.nanmin(rs[1:-1]) ymax7 = numpy.nanmax(rs[1:-1]) ymin8 = numpy.nanmin(ch[1:-1]) ymax8 = numpy.nanmax(ch[1:-1]) xr = xmax - xmin yr1 = ymax1 - ymin1 yr2 = ymax2 - ymin2 yr3 = ymax3 - ymin3 yr4 = ymax4 - ymin4 yr5 = ymax5 - ymin5 yr6 = ymax6 - ymin6 yr7 = ymax7 - ymin7 yr8 = ymax8 - ymin8 fl[i] = numpy.insert(fl[i],[0],[0.0]) fl[i] = numpy.append(fl[i],0.0) # plot style try: params = {'backend': 'png', 'axes.linewidth': 2.5, 'axes.labelsize': 24, 'axes.font': 'sans-serif', 'axes.fontweight' : 'bold', 'text.fontsize': 12, 'legend.fontsize': 12, 'xtick.labelsize': 12, 'ytick.labelsize': 12} pylab.rcParams.update(params) except: pass # define size of plot on monitor screen pylab.figure(str(i+1) + ' ' + str(time.asctime(time.localtime())),figsize=[12,16]) # delete any fossil plots in the matplotlib window pylab.clf() # position first axes inside the plotting window ax = pylab.axes([0.11,0.523,0.78,0.45]) # force tick labels to be absolute rather than relative pylab.gca().xaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.gca().yaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) # no x-label pylab.setp(pylab.gca(),xticklabels=[]) # plot flux vs time ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') dt = 0 work1 = 2.0 * cadence / 86400 for j in range(1,len(t)-1): dt = t[j] - t[j-1] if dt < work1: ltime = numpy.append(ltime,t[j]) ldata = numpy.append(ldata,fl[i][j]) else: pylab.plot(ltime,ldata,color='#0000ff',linestyle='-',linewidth=1.0) ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') pylab.plot(ltime,ldata,color='#0000ff',linestyle='-',linewidth=1.0) # plot the fill color below data time series, with no data gaps pylab.fill(t,fl[i],fc='#ffff00',linewidth=0.0,alpha=0.2) # define plot x and y limits pylab.xlim(xmin - xr * 0.01, xmax + xr * 0.01) if ymin1 - yr1 * 0.01 <= 0.0: pylab.ylim(1.0e-10, ymax1 + yr1 * 0.01) else: pylab.ylim(ymin1 - yr1 * 0.01, ymax1 + yr1 * 0.01) # plot labels # pylab.xlabel(xlab, {'color' : 'k'}) try: pylab.ylabel('Source (' + ylab1 + ')', {'color' : 'k'}) except: ylab1 = '10**%d e-/s' % nrm pylab.ylabel('Source (' + ylab1 + ')', {'color' : 'k'}) # make grid on plot pylab.grid() # plot centroid tracks - position second axes inside the plotting window if focus and background: axs = [0.11,0.433,0.78,0.09] elif background or focus: axs = [0.11,0.388,0.78,0.135] else: axs = [0.11,0.253,0.78,0.27] ax1 = pylab.axes(axs) # force tick labels to be absolute rather than relative pylab.gca().xaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.gca().yaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.setp(pylab.gca(),xticklabels=[]) # plot dx vs time ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') dt = 0 work1 = 2.0 * cadence / 86400 for j in range(1,len(t)-1): dt = t[j] - t[j-1] if dt < work1: ltime = numpy.append(ltime,t[j]) ldata = numpy.append(ldata,xx[j-1]) else: ax1.plot(ltime,ldata,color='r',linestyle='-',linewidth=1.0) ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') ax1.plot(ltime,ldata,color='r',linestyle='-',linewidth=1.0) # define plot x and y limits pylab.xlim(xmin - xr * 0.01, xmax + xr * 0.01) pylab.ylim(ymin2 - yr2 * 0.03, ymax2 + yr2 * 0.03) # plot labels ax1.set_ylabel('X-' + ylab2, color='k', fontsize=11) # position second axes inside the plotting window ax2 = ax1.twinx() # force tick labels to be absolute rather than relative pylab.gca().xaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.gca().yaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.setp(pylab.gca(),xticklabels=[]) # plot dy vs time ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') dt = 0 work1 = 2.0 * cadence / 86400 for j in range(1,len(t)-1): dt = t[j] - t[j-1] if dt < work1: ltime = numpy.append(ltime,t[j]) ldata = numpy.append(ldata,yy[j-1]) else: ax2.plot(ltime,ldata,color='g',linestyle='-',linewidth=1.0) ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') ax2.plot(ltime,ldata,color='g',linestyle='-',linewidth=1.0) # define plot y limits pylab.xlim(xmin - xr * 0.01, xmax + xr * 0.01) pylab.ylim(ymin3 - yr3 * 0.03, ymax3 + yr3 * 0.03) # plot labels ax2.set_ylabel('Y-' + ylab2, color='k',fontsize=11) # background - position third axes inside the plotting window if background and focus: axs = [0.11,0.343,0.78,0.09] if background and not focus: axs = [0.11,0.253,0.78,0.135] if background: ax1 = pylab.axes(axs) # force tick labels to be absolute rather than relative pylab.gca().xaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.gca().yaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.setp(pylab.gca(),xticklabels=[]) # plot background vs time ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') dt = 0 work1 = 2.0 * cadence / 86400 for j in range(1,len(t)-1): dt = t[j] - t[j-1] if dt < work1: ltime = numpy.append(ltime,t[j]) ldata = numpy.append(ldata,bg[j]) else: ax1.plot(ltime,ldata,color='#0000ff',linestyle='-',linewidth=1.0) ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') ax1.plot(ltime,ldata,color='#0000ff',linestyle='-',linewidth=1.0) # plot the fill color below data time series, with no data gaps pylab.fill(t,bg,fc='#ffff00',linewidth=0.0,alpha=0.2) # define plot x and y limits pylab.xlim(xmin - xr * 0.01, xmax + xr * 0.01) pylab.ylim(ymin4 - yr4 * 0.03, ymax4 + yr4 * 0.03) # plot labels ax1.set_ylabel('Background \n(e$^-$ s$^{-1}$ pix$^{-1}$)', multialignment='center', color='k',fontsize=11) # make grid on plot pylab.grid() # position focus axes inside the plotting window if focus and background: axs = [0.11,0.253,0.78,0.09] if focus and not background: axs = [0.11,0.253,0.78,0.135] if focus: ax1 = pylab.axes(axs) # force tick labels to be absolute rather than relative pylab.gca().xaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.gca().yaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.setp(pylab.gca(),xticklabels=[]) # plot x-axis PSF width vs time ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') dt = 0 work1 = 2.0 * cadence / 86400 for j in range(1,len(t)-1): dt = t[j] - t[j-1] if dt < work1: ltime = numpy.append(ltime,t[j]) ldata = numpy.append(ldata,fx[j]) else: ax1.plot(ltime,ldata,color='r',linestyle='-',linewidth=1.0) ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') ax1.plot(ltime,ldata,color='r',linestyle='-',linewidth=1.0) # plot y-axis PSF width vs time ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') dt = 0 work1 = 2.0 * cadence / 86400 for j in range(1,len(t)-1): dt = t[j] - t[j-1] if dt < work1: ltime = numpy.append(ltime,t[j]) ldata = numpy.append(ldata,fy[j]) else: ax1.plot(ltime,ldata,color='g',linestyle='-',linewidth=1.0) ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') ax1.plot(ltime,ldata,color='g',linestyle='-',linewidth=1.0) # define plot x and y limits pylab.xlim(xmin - xr * 0.01, xmax + xr * 0.01) pylab.ylim(ymin5 - yr5 * 0.03, ymax5 + yr5 * 0.03) # plot labels ax1.set_ylabel('Pixel Scale\nFactor', multialignment='center', color='k',fontsize=11) # Focus rotation - position second axes inside the plotting window ax2 = ax1.twinx() # force tick labels to be absolute rather than relative pylab.gca().xaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.gca().yaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.setp(pylab.gca(),xticklabels=[]) # plot dy vs time ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') dt = 0 work1 = 2.0 * cadence / 86400 for j in range(1,len(t)-1): dt = t[j] - t[j-1] if dt < work1: ltime = numpy.append(ltime,t[j]) ldata = numpy.append(ldata,fa[j]) else: ax2.plot(ltime,ldata,color='#000080',linestyle='-',linewidth=1.0) ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') ax2.plot(ltime,ldata,color='#000080',linestyle='-',linewidth=1.0) # define plot y limits pylab.xlim(xmin - xr * 0.01, xmax + xr * 0.01) pylab.ylim(ymin6 - yr6 * 0.03, ymax6 + yr6 * 0.03) # plot labels ax2.set_ylabel('Rotation (deg)', color='k',fontsize=11) # fit residuals - position fifth axes inside the plotting window axs = [0.11,0.163,0.78,0.09] ax1 = pylab.axes(axs) # force tick labels to be absolute rather than relative pylab.gca().xaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.gca().yaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.setp(pylab.gca(),xticklabels=[]) # plot residual vs time ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') dt = 0 work1 = 2.0 * cadence / 86400 for j in range(1,len(t)-1): dt = t[j] - t[j-1] if dt < work1: ltime = numpy.append(ltime,t[j]) ldata = numpy.append(ldata,rs[j]) else: ax1.plot(ltime,ldata,color='b',linestyle='-',linewidth=1.0) ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') ax1.plot(ltime,ldata,color='b',linestyle='-',linewidth=1.0) # plot the fill color below data time series, with no data gaps pylab.fill(t,rs,fc='#ffff00',linewidth=0.0,alpha=0.2) # define plot x and y limits pylab.xlim(xmin - xr * 0.01, xmax + xr * 0.01) pylab.ylim(ymin7 - yr7 * 0.03, ymax7 + yr7 * 0.03) # plot labels ax1.set_ylabel('Residual \n(e$^-$ s$^{-1}$)', multialignment='center', color='k',fontsize=11) # make grid on plot pylab.grid() # fit chi square - position sixth axes inside the plotting window axs = [0.11,0.073,0.78,0.09] ax1 = pylab.axes(axs) # force tick labels to be absolute rather than relative pylab.gca().xaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.gca().yaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) # plot background vs time ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') dt = 0 work1 = 2.0 * cadence / 86400 for j in range(1,len(t)-1): dt = t[j] - t[j-1] if dt < work1: ltime = numpy.append(ltime,t[j]) ldata = numpy.append(ldata,ch[j]) else: ax1.plot(ltime,ldata,color='b',linestyle='-',linewidth=1.0) ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') ax1.plot(ltime,ldata,color='b',linestyle='-',linewidth=1.0) # plot the fill color below data time series, with no data gaps pylab.fill(t,ch,fc='#ffff00',linewidth=0.0,alpha=0.2) # define plot x and y limits pylab.xlim(xmin - xr * 0.01, xmax + xr * 0.01) pylab.ylim(ymin8 - yr8 * 0.03, ymax8 + yr8 * 0.03) # plot labels ax1.set_ylabel('$\chi^2$ (%d dof)' % (npix-len(guess)-1),color='k',fontsize=11) pylab.xlabel(xlab, {'color' : 'k'}) # make grid on plot pylab.grid() # render plot if status == 0: pylab.savefig(outroot + '_' + str(i) + '.png') if status == 0 and plt: if cmdLine: pylab.show(block=True) else: pylab.ion() pylab.plot([]) pylab.ioff() # stop time kepmsg.clock('\n\nKEPPRFPHOT ended at',logfile,verbose) return
def kepfake(outfile,prfdir,module,output,column,row,kepmag,background,xdim,ydim, clobber,verbose,logfile,status,cmdLine=False): # input arguments status = 0 seterr(all="ignore") # log the call hashline = '----------------------------------------------------------------------------' kepmsg.log(logfile,hashline,verbose) call = 'KEPFAKE -- ' call += 'outfile='+outfile+' ' call += 'prfdir='+prfdir+' ' call += 'module='+str(module)+' ' call += 'output='+str(output)+' ' call += 'column='+str(column)+' ' call += 'row='+str(row)+' ' call += 'kepmag='+str(kepmag)+' ' call += 'background='+str(background)+' ' call += 'xdim='+str(xdim)+' ' call += 'ydim='+str(ydim)+' ' clob = 'n' if (clobber): clob = 'y' call += 'clobber='+clob+' ' chatter = 'n' if (verbose): chatter = 'y' call += 'verbose='+chatter+' ' call += 'logfile='+logfile kepmsg.log(logfile,call+'\n',verbose) # test log file logfile = kepmsg.test(logfile) # plot style if status == 0: try: params = {'backend': 'png', 'axes.linewidth': 2.5, 'axes.labelsize': 24, 'axes.font': 'sans-serif', 'axes.fontweight' : 'bold', 'text.fontsize': 12, 'legend.fontsize': 12, 'xtick.labelsize': 10, 'ytick.labelsize': 10} pylab.rcParams.update(params) except: pass pylab.figure(figsize=[12,12]) pylab.clf() # start time kepmsg.clock('KEPFAKE started at',logfile,verbose) # clobber output file if status == 0: if clobber: status = kepio.clobber(outfile,logfile,verbose) if kepio.fileexists(outfile): message = 'ERROR -- KEPPRFPHOT: ' + outfile + ' exists. Use --clobber' status = kepmsg.err(logfile,message,verbose) # Create time-tagged arrays if status == 0: nobs = 192 time = zeros((nobs)) timecorr = zeros((nobs)) cadenceno = zeros((nobs)) raw_cnts = zeros((nobs,ydim,xdim)) flux = zeros((nobs,ydim,xdim)) flux_err = zeros((nobs,ydim,xdim)) flux_bkg = zeros((nobs,ydim,xdim)) flux_bkg_err = zeros((nobs,ydim,xdim)) cosmic_rays = zeros((nobs,ydim,xdim)) quality = zeros((nobs)) pos_corr1 = zeros((nobs)) pos_corr2 = zeros((nobs)) # Create aperture bit mqp if status == 0: aperture = ones((ydim,xdim)) * 3.0 # determine suitable PRF calibration file if status == 0: if int(module) < 10: prefix = 'kplr0' else: prefix = 'kplr' prfglob = prfdir + '/' + prefix + str(module) + '.' + str(output) + '*' + '_prf.fits' try: prffile = glob.glob(prfglob)[0] except: message = 'ERROR -- KEPFAKE: No PRF file found in ' + prfdir status = kepmsg.err(logfile,message,verbose) # read PRF images if status == 0: prfn = [0,0,0,0,0] crpix1p = numpy.zeros((5),dtype='float32') crpix2p = numpy.zeros((5),dtype='float32') crval1p = numpy.zeros((5),dtype='float32') crval2p = numpy.zeros((5),dtype='float32') cdelt1p = numpy.zeros((5),dtype='float32') cdelt2p = numpy.zeros((5),dtype='float32') for i in range(5): prfn[i], crpix1p[i], crpix2p[i], crval1p[i], crval2p[i], cdelt1p[i], cdelt2p[i], status \ = kepio.readPRFimage(prffile,i+1,logfile,verbose) PRFx = arange(0.5,shape(prfn[0])[1]+0.5) PRFy = arange(0.5,shape(prfn[0])[0]+0.5) PRFx = (PRFx - size(PRFx) / 2) * cdelt1p[0] PRFy = (PRFy - size(PRFy) / 2) * cdelt2p[0] # interpolate the calibrated PRF shape to the target position if status == 0: prf = zeros(shape(prfn[0]),dtype='float32') prfWeight = zeros((5),dtype='float32') for i in range(5): prfWeight[i] = sqrt((column - crval1p[i])**2 + (row - crval2p[i])**2) if prfWeight[i] == 0.0: prfWeight[i] = 1.0e6 prf = prf + prfn[i] / prfWeight[i] prf = prf / nansum(prf) / cdelt1p[0] / cdelt2p[0] # interpolation function over the PRF if status == 0: splineInterpolation = scipy.interpolate.RectBivariateSpline(PRFx,PRFy,prf,kx=3,ky=3) # flux from target if status == 0: zeropoint = 33.227 kepflux = 10.0**((zeropoint - kepmag) / 2.5) # range of the output image in detector coordinates if status == 0: if xdim % 2 == 0: xdim += 1 if ydim % 2 == 0: ydim += 1 DATx = arange(round(column) - floor(xdim/2),round(column) + floor(xdim/2) + 1.0) DATy = arange(round(row) - floor(ydim/2),round(row) + floor(ydim/2) + 1.0) ax = pylab.axes([0.05,0.5,0.45,0.45]) pylab.imshow(log10(prf+0.001),aspect='auto',interpolation='nearest',origin='lower',cmap='jet', extent=(min(PRFx),max(PRFx),min(PRFy),max(PRFy))) pylab.plot([-100.,100.],[0.0,0.0],'k',ls='--') pylab.plot([0.0,0.0],[-100.,100.],'k',ls='--') pylab.xlim(min(PRFx),max(PRFx)) pylab.ylim(min(PRFy),max(PRFy)) ax = pylab.axes([0.5,0.5,0.45,0.45]) TMPx = arange(min(PRFx),max(PRFx),0.1) + floor(column) TMPy = arange(min(PRFy),max(PRFy),0.1) + floor(row) PRFfit = kepfunc.PRF2DET([kepflux],[column],[row],TMPx,TMPy,1.0,1.0,0.0,splineInterpolation) PRFfit = PRFfit + background pylab.imshow(log10(PRFfit),aspect='auto',interpolation='nearest',origin='lower',cmap='jet', extent=(min(TMPx),max(TMPx),min(TMPy),max(TMPy))) pylab.plot([column,column],[-100.,2000.],'k',ls='--') pylab.plot([-100.,2000.],[row,row],'k',ls='--') pylab.xlim(min(TMPx),max(TMPx)) pylab.ylim(min(TMPy),max(TMPy)) ax = pylab.axes([0.05,0.05,0.45,0.45]) TMPx = arange(min(PRFx),max(PRFx),0.5) + floor(column) TMPy = arange(min(PRFy),max(PRFy),0.5) + floor(row) PRFfit = kepfunc.PRF2DET([kepflux],[column],[row],TMPx,TMPy,1.0,1.0,0.0,splineInterpolation) PRFfit = PRFfit + background pylab.imshow(log10(PRFfit),aspect='auto',interpolation='nearest',origin='lower',cmap='jet', extent=(min(TMPx),max(TMPx),min(TMPy),max(TMPy))) pylab.plot([column,column],[-100.,2000.],'k',ls='--') pylab.plot([-100.,2000.],[row,row],'k',ls='--') pylab.xlim(min(TMPx),max(TMPx)) pylab.ylim(min(TMPy),max(TMPy)) ax = pylab.axes([0.5,0.05,0.45,0.45]) TMPx = arange(min(PRFx),max(PRFx+1.0),1.0) + floor(column) - 0.5 TMPy = arange(min(PRFy),max(PRFy+1.0),1.0) + floor(row) - 0.5 PRFfit = kepfunc.PRF2DET([kepflux],[column],[row],TMPx,TMPy,1.0,1.0,0.0,splineInterpolation) PRFfit = PRFfit + background pylab.imshow(log10(PRFfit),aspect='auto',interpolation='nearest',origin='lower',cmap='jet', extent=(min(TMPx)-0.5,max(TMPx)-0.5,min(TMPy)-0.5,max(TMPy)-0.5)) pylab.plot([column,column],[-100.,2000.],'k',ls='--') pylab.plot([-100.,2000.],[row,row],'k',ls='--') pylab.xlim(min(TMPx),max(TMPx)) pylab.ylim(min(TMPy),max(TMPy)) pylab.ion() pylab.plot([]) pylab.ioff() # sys.exit() # location of the data image centered on the PRF image (in PRF pixel units) if status == 0: prfDimY = int(ydim / cdelt1p[0]) prfDimX = int(xdim / cdelt2p[0]) PRFy0 = (shape(prf)[0] - prfDimY) / 2 PRFx0 = (shape(prf)[1] - prfDimX) / 2 # iterate over each exposure if status == 0: for i in range(nobs): # for i in range(1): # constuct model PRF in detector coordinates if status == 0: PRFfit = kepfunc.PRF2DET([kepflux],[column],[row],DATx,DATy,1.0,1.0,0.0,splineInterpolation) PRFfit = PRFfit + background # add noise to image if status == 0: for index,value in ndenumerate(PRFfit): PRFfit[index] += sqrt(value) * kepfunc.inv_normal_cummulative_function(random.random()) # populate output array if status == 0: time[i] = 1500.2 + float(i) * 0.020416667 cadenceno[i] = 10000 + i flux[i,:,:] = PRFfit flux_err[i,:,:] = sqrt(PRFfit) pylab.imshow(log10(PRFfit),aspect='auto',interpolation='nearest',origin='lower',cmap='jet', extent=(min(DATx),max(DATx),min(DATy),max(DATy))) pylab.ion() pylab.plot([]) pylab.ioff() # Create the outfile primary extension if status == 0: hdu0 = PrimaryHDU() hdu0.header.update('EXTNAME','PRIMARY','name of extension') hdu0.header.update('EXTEND',True,'file may contain standard extensions') hdu0.header.update('EXTVER',1.0,'extension version number') hdu0.header.update('ORIGIN','NASA/Ames','organization that generated this file') hdu0.header.update('DATE','2014-04-08','file creation date') hdu0.header.update('CREATOR','FluxExporter-91415','SW version used to create this file') hdu0.header.update('PROCVER',11.0,'processing script version') hdu0.header.update('FILEVER','COA','file format version') hdu0.header.update('TIMVERSN','OGIP/93-003','OGIP memo number for file format') hdu0.header.update('TELESCOP','Kepler','telescope') hdu0.header.update('INSTRUME','Kepler photometer','detector type') hdu0.header.update('OBJECT','KIC 12345678','string version of kepID') hdu0.header.update('KEPLERID',1234567,'unique Kepler target identifier') hdu0.header.update('CHANNEL',58,'CCD channel') hdu0.header.update('SKYGROUP',32,'roll-independent location of channel') hdu0.header.update('MODULE',17,'CCD module') hdu0.header.update('OUTPUT',2,'CCD output') hdu0.header.update('QUARTER',4,'mission quarter during which data was collected') hdu0.header.update('SEASON',2,'mission season during which data was collected') hdu0.header.update('DATA_REL',25,'version of data release notes describing data') hdu0.header.update('OBSMODE','long cadence','observing mode') hdu0.header.update('RADESYS','ICRS','reference frame of celestial coordinates') hdu0.header.update('RA_OBJ',0.0,'[deg] right ascension from KIC') hdu0.header.update('DEC_OBJ',0.0,'[deg] declination from KIC') hdu0.header.update('EQUINOX',2000.0,'equinox of celestial coordinate system') hdu0.header.update('PMRA',0.0,'[arcsec/yr] RA proper motion') hdu0.header.update('PMDEC',0.0,'[arcsec/yr] Dec proper motion') hdu0.header.update('PMTOTAL',0.0,'[arcsec/yr] total proper motion') hdu0.header.update('PARALLAX',0.0,'[arcsec] parallax') hdu0.header.update('GLON',0.0,'[deg] galactic longitude') hdu0.header.update('GLAT',0.0,'[deg] galactic latitude') hdu0.header.update('GMAG',kepmag,'[mag] SDSS g band magnitude from KIC') hdu0.header.update('RMAG',kepmag,'[mag] SDSS r band magnitude from KIC') hdu0.header.update('IMAG',kepmag,'[mag] SDSS i band magnitude from KIC') hdu0.header.update('ZMAG',kepmag,'[mag] SDSS z band magnitude from KIC') hdu0.header.update('D51MAG',kepmag,'[mag] D51 magnitude, from KIC') hdu0.header.update('JMAG',kepmag,'[mag] J band magnitude from 2MASS') hdu0.header.update('HMAG',kepmag,'[mag] H band magnitude from 2MASS') hdu0.header.update('KMAG',kepmag,'[mag] K band magnitude from 2MASS') hdu0.header.update('KEPMAG',kepmag,'[mag] Kepler magnitude (Kp) from KIC') hdu0.header.update('GRCOLOR',0.0,'[mag] (g-r) color, SDSS bands') hdu0.header.update('JKCOLOR',0.0,'[mag] (J-K) color, 2MASS bands') hdu0.header.update('GKCOLOR',0.0,'[mag] (g-K) color, SDSS g - 2MASS K') hdu0.header.update('TEFF',5000.0,'[K] effective temperature from KIC') hdu0.header.update('LOGG',4.5,'[cm/s2] log10 surface gravity from KIC') hdu0.header.update('FEH',0.0,'[log10([Fe/H])] metallicity from KIC') hdu0.header.update('EBMINUSV',0.0,'[mag] E(B-V) redenning from KIC') hdu0.header.update('AV',0.0,'[mag] A_v extinction from KIC') hdu0.header.update('RADIUS',1.0,'[solar radii] stellar radius from KIC') hdu0.header.update('TMINDEX',1117146912,'unique 2MASS catalog ID from KIC') hdu0.header.update('SCPID',1117146912,'unique SCP processing ID from KIC') hdulist = HDUList(hdu0) # create the outfile table extension if status == 0: eformat = str(ydim*xdim) + 'E' jformat = str(ydim*xdim) + 'J' kformat = str(ydim*xdim) + 'K' coldim = '(' + str(ydim) + ',' + str(ydim) + ')' col1 = Column(name='TIME',format='D',unit='BJD - 2454833',array=time) col2 = Column(name='TIMECORR',format='E',unit='d',array=timecorr) col3 = Column(name='CADENCENO',format='J',array=cadenceno) col4 = Column(name='RAW_CNTS',format=jformat,unit='count',dim=coldim,array=raw_cnts) col5 = Column(name='FLUX',format=eformat,unit='e-/s',dim=coldim,array=flux) col6 = Column(name='FLUX_ERR',format=eformat,unit='e-/s',dim=coldim,array=flux_err) col7 = Column(name='FLUX_BKG',format=eformat,unit='e-/s',dim=coldim,array=flux_bkg) col8 = Column(name='FLUX_BKG_ERR',format=eformat,unit='e-/s',dim=coldim,array=flux_bkg_err) col9 = Column(name='COSMIC_RAYS',format=eformat,unit='e-/s',dim=coldim,array=cosmic_rays) col10 = Column(name='QUALITY',format='J',array=quality) col11 = Column(name='POS_CORR1',format='E',unit='pixel',array=pos_corr1) col12 = Column(name='POS_CORR2',format='E',unit='pixel',array=pos_corr2) cols = ColDefs([col1,col2,col3,col4,col5,col6,col7,col8,col9,col10,col11,col12]) hdu1 = new_table(cols) hdu1.header.update('TTYPE1','TIME','column title: data time stamps') hdu1.header.update('TFORM1','D','data type: float64') hdu1.header.update('TUNIT1','BJD - 2454833','column units: barycenter corrected JD') hdu1.header.update('TDISP1','D13.7','column display format') hdu1.header.update('TTYPE2','TIMECORR','column title: barycentric correction') hdu1.header.update('TFORM2','E','column format: float32') hdu1.header.update('TUNIT2','d','column units: days') hdu1.header.update('TDISP2','D12.7','column display format') hdu1.header.update('TTYPE3','CADENCENO','column title: unique cadence number') hdu1.header.update('TFORM3','J','column format: signed integer32') hdu1.header.update('TTYPE4','RAW_CNTS','column title: raw pixel count') hdu1.header.update('TFORM4',jformat,'column format: signed integer32') hdu1.header.update('TDIM4',coldim,'column dimensions: pixel apeture array') hdu1.header.update('TUNIT4','count','column units: count') hdu1.header.update('TTYPE5','FLUX','column title: calibrated pixel flux') hdu1.header.update('TFORM5',eformat,'column format: float32') hdu1.header.update('TDIM5',coldim,'column dimensions: pixel apeture array') hdu1.header.update('TUNIT5','e-/s','column units: electrons per second') hdu1.header.update('TTYPE6','FLUX_ERR','column title: 1-sigma calibrated uncertainty') hdu1.header.update('TFORM6',eformat,'column format: float32') hdu1.header.update('TDIM6',coldim,'column dimensions: pixel apeture array') hdu1.header.update('TUNIT6','e-/s','column units: electrons per second (1-sigma)') hdu1.header.update('TTYPE7','FLUX_BKG','column title: calibrated background flux') hdu1.header.update('TFORM7',eformat,'column format: float32') hdu1.header.update('TDIM7',coldim,'column dimensions: pixel apeture array') hdu1.header.update('TUNIT7','e-/s','column units: electrons per second') hdu1.header.update('TTYPE8','FLUX_BKG_ERR','column title: 1-sigma cal. backgrnd uncertainty') hdu1.header.update('TFORM8',eformat,'column format: float32') hdu1.header.update('TDIM8',coldim,'column dimensions: pixel apeture array') hdu1.header.update('TUNIT8','e-/s','column units: electrons per second (1-sigma)') hdu1.header.update('TTYPE9','COSMIC_RAYS','column title: cosmic ray detections') hdu1.header.update('TFORM9',eformat,'column format: float32') hdu1.header.update('TDIM9',coldim,'column dimensions: pixel apeture array') hdu1.header.update('TUNIT9','e-/s','column units: electrons per second') hdu1.header.update('TTYPE10','QUALITY','column title: pixel quality flags') hdu1.header.update('TFORM10','J','column format: signed integer32') hdu1.header.update('TTYPE11','POS_CORR1','column title: col correction for vel. abbern') hdu1.header.update('TFORM11','E','column format: float32') hdu1.header.update('TUNIT11','pixel','column units: pixel') hdu1.header.update('TTYPE12','POS_CORR2','column title: row correction for vel. abbern') hdu1.header.update('TFORM12','E','column format: float32') hdu1.header.update('TUNIT12','pixel','column units: pixel') hdu1.header.update('WCAX4',2,'number of WCS axes') hdu1.header.update('1CTY4P','RAWX','right ascension coordinate type') hdu1.header.update('2CTY4P','RAWY','declination coordinate type') hdu1.header.update('1CRP4P',1,'[pixel] reference pixel along image axis 1') hdu1.header.update('2CRP4P',1,'[pixel] reference pixel along image axis 2') hdu1.header.update('1CRV4P',DATx[0],'[pixel] detector coordinate at reference pixel') hdu1.header.update('2CRV4P',DATy[0],'[pixel] detector coordinate at reference pixel') hdu1.header.update('1CUN4P','pixel','physical unit in column dimension') hdu1.header.update('2CUN4P','pixel','physical unit in row dimension') hdu1.header.update('1CDE4P',1.0,'[pixel] pixel scale in column dimension') hdu1.header.update('2CDE4P',1.0,'[pixel] pixel scale in row dimension') hdu1.header.update('1CTYP4','RA---TAN','right ascension coordinate type') hdu1.header.update('2CTYP4','DEC--TAN','declination coordinate type') hdu1.header.update('1CRPX4',int(xdim/2),'[pixel] reference pixel along image axis 1') hdu1.header.update('2CRPX4',int(ydim/2),'[pixel] reference pixel along image axis 2') hdu1.header.update('1CRVL4',294.94017,'[deg] right ascension at reference pixel') hdu1.header.update('2CRVL4',43.80033,'[deg] declination at reference pixel') hdu1.header.update('1CUNI4','deg','physical unit in column dimension') hdu1.header.update('2CUNI4','deg','physical unit in row dimension') hdu1.header.update('1CDLT4',-0.001106815552144,'[deg] pixel scale in RA dimension') hdu1.header.update('2CDLT4',0.001106815552144,'[deg] pixel scale in Dec dimension') hdu1.header.update('11PC4',0.46086006096337634,'linear transformation matrix element cos(th)') hdu1.header.update('12PC4',-0.8897046441865888,'linear transformation matrix element -sin(th)') hdu1.header.update('21PC4',0.8864170184391076,'linear transformation matrix element sin(th)') hdu1.header.update('22PC4',0.45860051653617395,'linear transformation matrix element cos(th)') hdu1.header.update('WCAX5',2,'number of WCS axes') hdu1.header.update('1CTY5P','RAWX','right ascension coordinate type') hdu1.header.update('2CTY5P','RAWY','declination coordinate type') hdu1.header.update('1CRP5P',1,'[pixel] reference pixel along image axis 1') hdu1.header.update('2CRP5P',1,'[pixel] reference pixel along image axis 2') hdu1.header.update('1CRV5P',DATx[0],'[pixel] detector coordinate at reference pixel') hdu1.header.update('2CRV5P',DATy[0],'[pixel] detector coordinate at reference pixel') hdu1.header.update('1CUN5P','pixel','physical unit in column dimension') hdu1.header.update('2CUN5P','pixel','physical unit in row dimension') hdu1.header.update('1CDE5P',1.0,'[pixel] pixel scale in column dimension') hdu1.header.update('2CDE5P',1.0,'[pixel] pixel scale in row dimension') hdu1.header.update('1CTYP5','RA---TAN','right ascension coordinate type') hdu1.header.update('2CTYP5','DEC--TAN','declination coordinate type') hdu1.header.update('1CRPX5',int(xdim/2),'[pixel] reference pixel along image axis 1') hdu1.header.update('2CRPX5',int(ydim/2),'[pixel] reference pixel along image axis 2') hdu1.header.update('1CRVL5',294.94017,'[deg] right ascension at reference pixel') hdu1.header.update('2CRVL5',43.80033,'[deg] declination at reference pixel [deg]') hdu1.header.update('1CUNI5','deg','physical unit in column dimension') hdu1.header.update('2CUNI5','deg','physical unit in row dimension') hdu1.header.update('1CDLT5',-0.001106815552144,'[deg] pixel scale in RA dimension') hdu1.header.update('2CDLT5',0.001106815552144,'[deg] pixel scale in Dec dimension') hdu1.header.update('11PC5',0.46086006096337634,'linear transformation matrix element cos(th)') hdu1.header.update('12PC5',-0.8897046441865888,'linear transformation matrix element -sin(th)') hdu1.header.update('21PC5',0.8864170184391076,'linear transformation matrix element sin(th)') hdu1.header.update('22PC5',0.45860051653617395,'linear transformation matrix element cos(th)') hdu1.header.update('WCAX6',2,'number of WCS axes') hdu1.header.update('1CTY6P','RAWX','right ascension coordinate type') hdu1.header.update('2CTY6P','RAWY','declination coordinate type') hdu1.header.update('1CRP6P',1,'[pixel] reference pixel along image axis 1') hdu1.header.update('2CRP6P',1,'[pixel] reference pixel along image axis 2') hdu1.header.update('1CRV6P',DATx[0],'[pixel] detector coordinate at reference pixel') hdu1.header.update('2CRV6P',DATy[0],'[pixel] detector coordinate at reference pixel') hdu1.header.update('1CUN6P','pixel','physical unit in column dimension') hdu1.header.update('2CUN6P','pixel','physical unit in row dimension') hdu1.header.update('1CDE6P',1.0,'[pixel] pixel scale in column dimension') hdu1.header.update('2CDE6P',1.0,'[pixel] pixel scale in row dimension') hdu1.header.update('1CTYP6','RA---TAN','right ascension coordinate type') hdu1.header.update('2CTYP6','DEC--TAN','declination coordinate type') hdu1.header.update('1CRPX6',int(xdim/2),'[pixel] reference pixel along image axis 1') hdu1.header.update('2CRPX6',int(ydim/2),'[pixel] reference pixel along image axis 2') hdu1.header.update('1CRVL6',294.94017,'[deg] right ascension at reference pixel') hdu1.header.update('2CRVL6',43.80033,'[deg] declination at reference pixel') hdu1.header.update('1CUNI6','deg','physical unit in column dimension') hdu1.header.update('2CUNI6','deg','physical unit in row dimension') hdu1.header.update('1CDLT6',-0.00110558987335788,'[deg] pixel scale in RA dimension') hdu1.header.update('2CDLT6',0.00110558987335788,'[deg] pixel scale in Dec dimension') hdu1.header.update('11PC6',0.46086006096337634,'linear transformation matrix element cos(th)') hdu1.header.update('12PC6',-0.8897046441865888,'linear transformation matrix element -sin(th)') hdu1.header.update('21PC6',0.8864170184391076,'linear transformation matrix element sin(th)') hdu1.header.update('22PC6',0.45860051653617395,'linear transformation matrix element cos(th)') hdu1.header.update('WCAX7',2,'number of WCS axes') hdu1.header.update('1CTY7P','RAWX','right ascension coordinate type') hdu1.header.update('2CTY7P','RAWY','declination coordinate type') hdu1.header.update('1CRP7P',1,'[pixel] reference pixel along image axis 1') hdu1.header.update('2CRP7P',1,'[pixel] reference pixel along image axis 2') hdu1.header.update('1CRV7P',DATx[0],'[pixel] detector coordinate at reference pixel') hdu1.header.update('2CRV7P',DATy[0],'[pixel] detector coordinate at reference pixel') hdu1.header.update('1CUN7P','pixel','physical unit in column dimension') hdu1.header.update('2CUN7P','pixel','physical unit in row dimension') hdu1.header.update('1CDE7P',1.0,'[pixel] pixel scale in column dimension') hdu1.header.update('2CDE7P',1.0,'[pixel] pixel scale in row dimension') hdu1.header.update('1CTYP7','RA---TAN','right ascension coordinate type') hdu1.header.update('2CTYP7','DEC--TAN','declination coordinate type') hdu1.header.update('1CRPX7',int(xdim/2),'[pixel] reference pixel along image axis 1') hdu1.header.update('2CRPX7',int(ydim/2),'[pixel] reference pixel along image axis 2') hdu1.header.update('1CRVL7',294.94017,'[deg] right ascension at reference pixel') hdu1.header.update('2CRVL7',43.80033,'[deg] declination at reference pixel') hdu1.header.update('1CUNI7','deg','physical unit in column dimension') hdu1.header.update('2CUNI7','deg','physical unit in row dimension') hdu1.header.update('1CDLT7',-0.00110558987335788,'[deg] pixel scale in RA dimension') hdu1.header.update('2CDLT7',0.00110558987335788,'[deg] pixel scale in Dec dimension') hdu1.header.update('11PC7',0.46086006096337634,'linear transformation matrix element cos(th)') hdu1.header.update('12PC7',-0.8897046441865888,'linear transformation matrix element -sin(th)') hdu1.header.update('21PC7',0.8864170184391076,'linear transformation matrix element sin(th)') hdu1.header.update('22PC7',0.45860051653617395,'linear transformation matrix element cos(th)') hdu1.header.update('WCAX8',2,'number of WCS axes') hdu1.header.update('1CTY8P','RAWX','right ascension coordinate type') hdu1.header.update('2CTY8P','RAWY','declination coordinate type') hdu1.header.update('1CRP8P',1,'[pixel] reference pixel along image axis 1') hdu1.header.update('2CRP8P',1,'[pixel] reference pixel along image axis 2') hdu1.header.update('1CRV8P',DATx[0],'[pixel] detector coordinate at reference pixel') hdu1.header.update('2CRV8P',DATy[0],'[pixel] detector coordinate at reference pixel') hdu1.header.update('1CUN8P','pixel','physical unit in column dimension') hdu1.header.update('2CUN8P','pixel','physical unit in row dimension') hdu1.header.update('1CDE8P',1.0,'[pixel] pixel scale in column dimension') hdu1.header.update('2CDE8P',1.0,'[pixel] pixel scale in row dimension') hdu1.header.update('1CTYP8','RA---TAN','right ascension coordinate type') hdu1.header.update('2CTYP8','DEC--TAN','declination coordinate type') hdu1.header.update('1CRPX8',int(xdim/2),'[pixel] reference pixel along image axis 1') hdu1.header.update('2CRPX8',int(ydim/2),'[pixel] reference pixel along image axis 2') hdu1.header.update('1CRVL8',294.94017,'[deg] right ascension at reference pixel') hdu1.header.update('2CRVL8',43.80033,'[deg] declination at reference pixel') hdu1.header.update('1CUNI8','deg','physical unit in column dimension') hdu1.header.update('2CUNI8','deg','physical unit in row dimension') hdu1.header.update('1CDLT8',-0.00110558987335788,'[deg] pixel scale in RA dimension') hdu1.header.update('2CDLT8',0.00110558987335788,'[deg] pixel scale in Dec dimension') hdu1.header.update('11PC8',0.46086006096337634,'linear transformation matrix element cos(th)') hdu1.header.update('12PC8',-0.8897046441865888,'linear transformation matrix element -sin(th)') hdu1.header.update('21PC8',0.8864170184391076,'linear transformation matrix element sin(th)') hdu1.header.update('22PC8',0.45860051653617395,'linear transformation matrix element cos(th)') hdu1.header.update('WCAX9',2,'number of WCS axes') hdu1.header.update('1CTY9P','RAWX','right ascension coordinate type') hdu1.header.update('2CTY9P','RAWY','declination coordinate type') hdu1.header.update('1CRP9P',1,'[pixel] reference pixel along image axis 1') hdu1.header.update('2CRP9P',1,'[pixel] reference pixel along image axis 2') hdu1.header.update('1CRV9P',DATx[0],'[pixel] detector coordinate at reference pixel') hdu1.header.update('2CRV9P',DATy[0],'[pixel] detector coordinate at reference pixel') hdu1.header.update('1CUN9P','pixel','physical unit in column dimension') hdu1.header.update('2CUN9P','pixel','physical unit in row dimension') hdu1.header.update('1CDE9P',1.0,'[pixel] pixel scale in column dimension') hdu1.header.update('2CDE9P',1.0,'[pixel] pixel scale in row dimension') hdu1.header.update('1CTYP9','RA---TAN','right ascension coordinate type') hdu1.header.update('2CTYP9','DEC--TAN','declination coordinate type') hdu1.header.update('1CRPX9',int(xdim/2),'[pixel] reference pixel along image axis 1') hdu1.header.update('2CRPX9',int(ydim/2),'[pixel] reference pixel along image axis 2') hdu1.header.update('1CRVL9',294.94017,'[deg] right ascension at reference pixel') hdu1.header.update('2CRVL9',43.80033,'[deg] declination at reference pixel') hdu1.header.update('1CUNI9','deg','physical unit in column dimension') hdu1.header.update('2CUNI9','deg','physical unit in row dimension') hdu1.header.update('1CDLT9',-0.00110558987335788,'[deg] pixel scale in RA dimension') hdu1.header.update('2CDLT9',0.00110558987335788,'[deg] pixel scale in Dec dimension') hdu1.header.update('11PC9',0.46086006096337634,'linear transformation matrix element cos(th)') hdu1.header.update('12PC9',-0.8897046441865888,'linear transformation matrix element -sin(th)') hdu1.header.update('21PC9',0.8864170184391076,'linear transformation matrix element sin(th)') hdu1.header.update('22PC9',0.45860051653617395,'linear transformation matrix element cos(th)') hdu1.header.update('WCAX10',2,'number of WCS axes') hdu1.header.update('1CTY10P','RAWX','right ascension coordinate type') hdu1.header.update('2CTY10P','RAWY','declination coordinate type') hdu1.header.update('1CRP10P',1,'[pixel] reference pixel along image axis 1') hdu1.header.update('2CRP10P',1,'[pixel] reference pixel along image axis 2') hdu1.header.update('1CRV10P',DATx[0],'[pixel] detector coordinate at reference pixel') hdu1.header.update('2CRV10P',DATy[0],'[pixel] detector coordinate at reference pixel') hdu1.header.update('1CUN10P','pixel','physical unit in column dimension') hdu1.header.update('2CUN10P','pixel','physical unit in row dimension') hdu1.header.update('1CDE10P',1.0,'[pixel] pixel scale in column dimension') hdu1.header.update('2CDE10P',1.0,'[pixel] pixel scale in row dimension') hdu1.header.update('1CTYP10','RA---TAN','right ascension coordinate type') hdu1.header.update('2CTYP10','DEC--TAN','declination coordinate type') hdu1.header.update('1CRPX10',int(xdim/2),'[pixel] reference pixel along image axis 1') hdu1.header.update('2CRPX10',int(ydim/2),'[pixel] reference pixel along image axis 2') hdu1.header.update('1CRVL10',294.94017,'[deg] right ascension at reference pixel') hdu1.header.update('2CRVL10',43.80033,'[deg] declination at reference pixel') hdu1.header.update('1CUNI10','deg','physical unit in column dimension') hdu1.header.update('2CUNI10','deg','physical unit in row dimension') hdu1.header.update('1CDLT10',-0.00110558987335788,'[deg] pixel scale in RA dimension') hdu1.header.update('2CDLT10',0.00110558987335788,'[deg] pixel scale in Dec dimension') hdu1.header.update('11PC10',0.46086006096337634,'linear transformation matrix element cos(th)') hdu1.header.update('12PC10',-0.8897046441865888,'linear transformation matrix element -sin(th)') hdu1.header.update('21PC10',0.8864170184391076,'linear transformation matrix element sin(th)') hdu1.header.update('22PC10',0.45860051653617395,'linear transformation matrix element cos(th)') hdu1.header.update('INHERIT',True,'inherit primary keywords') hdu1.header.update('EXTNAME','TARGETTABLES','name of extension') hdu1.header.update('EXTVER',1,'extension version number') hdu1.header.update('TELESCOP','Kepler','telescope') hdu1.header.update('INSTRUME','Kepler photometer','detector type') hdu1.header.update('OBJECT','KIC 12345678','string version of kepID') hdu1.header.update('KEPLERID',12345678,'unique Kepler target identifier') hdu1.header.update('RADESYS','ICRS','reference frame of celestial coordinates') hdu1.header.update('RA_OBJ',0.0,'[deg] right ascension from KIC') hdu1.header.update('DEC_OBJ',0.0,'[deg] declination from KIC') hdu1.header.update('EQUINOX',2000.0,'equinox of celestial coordinate system') hdu1.header.update('TIMEREF','SOLARSYSTEM','barycentric correction applied to times') hdu1.header.update('TASSIGN','SPACECRAFT','where time is assigned') hdu1.header.update('TIMESYS','TDB','time system is barycentric JD') hdu1.header.update('BJDREFI',2454833,'integer part of BJD reference date') hdu1.header.update('BJDREFF',0.0,'fraction of day in BJD reference date') hdu1.header.update('TIMEUNIT','d','time unit for TIME, TSTART and TSTOP') hdu1.header.update('TSTART',1500.0,'observation start time in JD - BJDREF') hdu1.header.update('TSTOP',1504.0,'observation stop time in JD - BJDREF') hdu1.header.update('LC_START',1500.0+54833.5,'observation start time in MJD') hdu1.header.update('LC_END',1504.0+54833.5,'observation stop time in MJD') hdu1.header.update('TELAPSE',93.0,'[d] TSTOP - TSTART') hdu1.header.update('LIVETIME',82.7273,'[d] TELAPSE multiplied by DEADC') hdu1.header.update('EXPOSURE',82.7273,'[d] time on source') hdu1.header.update('DEADC',0.909091,'deadtime correction') hdu1.header.update('TIMEPIXR',0.5,'bin time beginning=0 middle=0.5 end=1') hdu1.header.update('TIERRELA',5.78e-7,'[d] relative time error') hdu1.header.update('TIERABSO',5.78e-6,'[d] absolute time error') hdu1.header.update('INT_TIME',6.0198,'[s] photon accumulation time per frame') hdu1.header.update('READTIME',0.518948526144,'[s] readout time per frame') hdu1.header.update('FRAMETIM',6.53875,'[s] frame time (INT_TIME + READTIME)') hdu1.header.update('NUM_FRM',270,'number of frames per time stamp') hdu1.header.update('TIMEDEL',30.0/1440,'[d] time resolution of data') hdu1.header.update('DATE-OBS','2014-09-30T12:28:48.0','TSTART as UT calendar date') hdu1.header.update('DATE-END','2014-10-02T11:02:24.0','TSTOP as UT calendar date') hdu1.header.update('BACKAPP',True,'background is subtracted') hdu1.header.update('DEADAPP',False,'deadtime applied') hdu1.header.update('VIGNAPP',False,'vignetting or collimator correction applied') hdu1.header.update('GAIN',104.88,'[electrons/count] channel gain') hdu1.header.update('READNOIS',0.7845*104.88,'[electrons] read noise') hdu1.header.update('NREADOUT',276,'number of reads per cadence') hdu1.header.update('TIMSLICE',3,'time-slice readout sequence section') hdu1.header.update('MEANBLCK',738,'[count] FSW mean black level') hdulist.append(hdu1) # create the outfile image extension if status == 0: hdu2 = ImageHDU(aperture) hdu2.header.update('INHERIT',True,'inherit primary keywords') hdu2.header.update('EXTNAME','APERTURE','extension name') hdu2.header.update('EXTVER',1,'extension version number') hdu2.header.update('TELESCOP','Kepler','telescope') hdu2.header.update('INSTRUME','Kepler photometer','detector type') hdu2.header.update('OBJECT','KIC 12345678','string version of kepID') hdu2.header.update('KEPLERID',1234567,'unique Kepler target identifier') hdu2.header.update('RADESYS','ICRS','reference frame of celestial coordinates') hdu2.header.update('RA_OBJ',294.94017,'[deg] right ascension from KIC') hdu2.header.update('DEC_OBJ',43.80033,'[deg] declination from KIC') hdu2.header.update('EQUINOX',2000.0,'equinox of celestial coordinate system') hdu2.header.update('WCSAXES',2,'number of WCS axes') hdu2.header.update('CTYPE1P','RAWX','pixel coordinate type') hdu2.header.update('CTYPE2P','RAWY','pixel coordinate type') hdu2.header.update('CRPIX1P',1,'[pixel] reference pixel along image axis 1') hdu2.header.update('CRPIX2P',1,'[pixel] reference pixel along image axis 2') hdu2.header.update('CRVAL1P',DATx[0],'[pixel] column number at reference pixel') hdu2.header.update('CRVAL2P',DATy[0],'[pixel] row number at reference pixel') hdu2.header.update('CUNIT1P','pixel','physical unit in column dimension') hdu2.header.update('CUNIT2P','pixel','physical unit in row dimension') hdu2.header.update('CDELT1P',1.0,'[pixel] pixel scale along columns') hdu2.header.update('CDELT2P',1.0,'[pixel] pixel scale along rows') hdu2.header.update('CTYPE1','RA---TAN','right ascension coordinate type') hdu2.header.update('CTYPE2','DEC--TAN','declination coordinate type') hdu2.header.update('CRPIX1',int(xdim/2),'[pixel] reference pixel along image axis 1') hdu2.header.update('CRPIX2',int(ydim/2),'[pixel] reference pixel along image axis 2') hdu2.header.update('CRVAL1',294.94017,'right ascension at reference pixel [deg]') hdu2.header.update('CRVAL2',43.80033,'declination at reference pixel [deg]') hdu2.header.update('CUNIT1','deg','physical unit in column dimension') hdu2.header.update('CUNIT2','deg','physical unit in row dimension') hdu2.header.update('CDELT1',-0.001106815552144,'pixel scale in RA dimension') hdu2.header.update('CDELT2',0.001106815552144,'pixel scale in Dec dimension') hdu2.header.update('PC1_1',0.46086006096337634,'linear transformation matrix element cos(th)') hdu2.header.update('PC1_2',-0.8897046441865888,'linear transformation matrix element -sin(th)') hdu2.header.update('PC2_1',0.8864170184391076,'linear transformation matrix element sin(th)') hdu2.header.update('PC2_2',0.45860051653617395,'linear transformation matrix element cos(th)') hdulist.append(hdu2) # write output file if status == 0: hdulist.writeto(outfile,checksum=True) # stop time kepmsg.clock('\nKEPFAKE ended at',logfile,verbose) return
def kepprf_AMC(infile, rownum, columns, rows, fluxes, border, background, focus, prfdir, xtol, ftol, verbose, logfile): # input arguments status = 0 seterr(all="ignore") # open FITS file and get header info + data instr = fits.open(infile, mode='readonly', memmap=True) crval1p = instr[0].header['CRVAL1P'] crval2p = instr[0].header['CRVAL2P'] # construct inital guess vector for fit if status == 0: guess = [] try: f = fluxes.strip().split(',') x = columns.strip().split(',') y = rows.strip().split(',') for i in xrange(len(f)): f[i] = float(f[i]) except: f = fluxes x = columns y = rows nsrc = len(f) for i in xrange(nsrc): try: guess.append(float(f[i])) except: message = 'ERROR -- KEPPRF: Fluxes must be floating point numbers' status = kepmsg.err(logfile, message, verbose) if status == 0: if len(x) != nsrc or len(y) != nsrc: message = 'ERROR -- KEPFIT:FITMULTIPRF: Guesses for rows, columns and ' message += 'fluxes must have the same number of sources' status = kepmsg.err(logfile, message, verbose) if status == 0: for i in xrange(nsrc): try: guess.append(float(x[i]) + crval1p) except: message = 'ERROR -- KEPPRF: Columns must be floating point numbers' status = kepmsg.err(logfile, message, verbose) if status == 0: for i in xrange(nsrc): try: guess.append(float(y[i]) + crval2p) except: message = 'ERROR -- KEPPRF: Rows must be floating point numbers' status = kepmsg.err(logfile, message, verbose) if status == 0 and background: if border == 0: guess.append(0.0) else: for i in range((border + 1) * 2): guess.append(0.0) if status == 0 and focus: guess.append(1.0) guess.append(1.0) guess.append(0.0) # Get data from image; then close it fluxpixels = instr[0].data[:] errpixels = np.array([sqrt(val) for val in fluxpixels]) module = instr[0].header['MODULE'] output = instr[0].header['OUTPUT'] instr.close() x[0] = str(int(x[0]) + crval1p) y[0] = str(int(y[0]) + crval2p) column = int(x[0]) - 3 row = int(y[0]) - 3 ## xdim = 11 ## ydim = 11 ## npix = 121 xdim = 7 ydim = 7 npix = 49 # construct input pixel image if status == 0: flux = fluxpixels[row - crval2p:row - crval2p + ydim, column - crval1p:column - crval1p + xdim] ferr = errpixels[row - crval2p:row - crval2p + ydim, column - crval1p:column - crval1p + xdim] isize = numpy.shape(flux)[0] jsize = numpy.shape(flux)[1] flux = numpy.reshape(flux, (isize * jsize)) ferr = numpy.reshape(ferr, (isize * jsize)) DATx = arange(column, column + xdim) DATy = arange(row, row + ydim) # if numpy.nanmin > 420000.0: flux -= 420000.0 # image scale and intensity limits of pixel data if status == 0: n = 0 DATimg = empty((ydim, xdim)) ERRimg = empty((ydim, xdim)) for i in range(ydim): for j in range(xdim): DATimg[i, j] = flux[n] ERRimg[i, j] = ferr[n] n += 1 # determine suitable PRF calibration file if status == 0: if int(module) < 10: prefix = 'kplr0' else: prefix = 'kplr' prfglob = prfdir + '/' + prefix + str(module) + '.' + str( output) + '*' + '_prf.fits' try: prffile = glob.glob(prfglob)[0] except: message = 'ERROR -- KEPPRF: No PRF file found in ' + prfdir status = kepmsg.err(logfile, message, verbose) # read PRF images if status == 0: prfn = [0, 0, 0, 0, 0] crpix1p = numpy.zeros((5), dtype='float32') crpix2p = numpy.zeros((5), dtype='float32') crval1p = numpy.zeros((5), dtype='float32') crval2p = numpy.zeros((5), dtype='float32') cdelt1p = numpy.zeros((5), dtype='float32') cdelt2p = numpy.zeros((5), dtype='float32') for i in range(5): prfn[i], crpix1p[i], crpix2p[i], crval1p[i], crval2p[i], cdelt1p[i], cdelt2p[i], status \ = kepio.readPRFimage(prffile,i+1,logfile,verbose) prfn = array(prfn) PRFx = arange(0.5, shape(prfn[0])[1] + 0.5) PRFy = arange(0.5, shape(prfn[0])[0] + 0.5) PRFx = (PRFx - size(PRFx) / 2) * cdelt1p[0] PRFy = (PRFy - size(PRFy) / 2) * cdelt2p[0] # interpolate the calibrated PRF shape to the target position if status == 0: prf = zeros(shape(prfn[0]), dtype='float32') prfWeight = zeros((5), dtype='float32') for i in xrange(5): prfWeight[i] = sqrt((column - crval1p[i])**2 + (row - crval2p[i])**2) if prfWeight[i] == 0.0: prfWeight[i] = 1.0e-6 prf = prf + prfn[i] / prfWeight[i] prf = prf / nansum(prf) / cdelt1p[0] / cdelt2p[0] # location of the data image centered on the PRF image (in PRF pixel units) if status == 0: prfDimY = int(ydim / cdelt1p[0]) prfDimX = int(xdim / cdelt2p[0]) PRFy0 = (shape(prf)[0] - prfDimY) / 2 PRFx0 = (shape(prf)[1] - prfDimX) / 2 # interpolation function over the PRF if status == 0: splineInterpolation = scipy.interpolate.RectBivariateSpline( PRFx, PRFy, prf) # construct mesh for background model if status == 0 and background: bx = numpy.arange(1., float(xdim + 1)) by = numpy.arange(1., float(ydim + 1)) xx, yy = numpy.meshgrid(numpy.linspace(bx.min(), bx.max(), xdim), numpy.linspace(by.min(), by.max(), ydim)) # fit PRF model to pixel data if status == 0: if focus and background: args = (DATx, DATy, DATimg, ERRimg, nsrc, border, xx, yy, splineInterpolation, float(x[0]), float(y[0])) ans = fmin_powell(kepfunc.PRFwithFocusAndBackground, guess, args=args, xtol=xtol, ftol=ftol, disp=False) elif focus and not background: args = (DATx, DATy, DATimg, ERRimg, nsrc, splineInterpolation, float(x[0]), float(y[0])) ans = fmin_powell(kepfunc.PRFwithFocus, guess, args=args, xtol=xtol, ftol=ftol, disp=False) elif background and not focus: args = (DATx, DATy, DATimg, ERRimg, nsrc, border, xx, yy, splineInterpolation, float(x[0]), float(y[0])) ans = fmin_powell(kepfunc.PRFwithBackground, guess, args=args, xtol=xtol, ftol=ftol, disp=False) else: args = (DATx, DATy, DATimg, ERRimg, nsrc, splineInterpolation, float(x[0]), float(y[0])) ans = fmin_powell(kepfunc.PRF, guess, args=args, xtol=xtol, ftol=ftol, disp=False) # pad the PRF data if the PRF array is smaller than the data array if status == 0: flux = [] OBJx = [] OBJy = [] PRFmod = numpy.zeros((prfDimY, prfDimX)) if PRFy0 < 0 or PRFx0 < 0.0: PRFmod = numpy.zeros((prfDimY, prfDimX)) superPRF = zeros((prfDimY + 1, prfDimX + 1)) superPRF[abs(PRFy0):abs(PRFy0) + shape(prf)[0], abs(PRFx0):abs(PRFx0) + shape(prf)[1]] = prf prf = superPRF * 1.0 PRFy0 = 0 PRFx0 = 0 # rotate the PRF model around its center if focus: angle = ans[-1] prf = rotate(prf, -angle, reshape=False, mode='nearest') # iterate through the sources in the best fit PSF model for i in range(nsrc): flux.append(ans[i]) OBJx.append(ans[nsrc + i]) OBJy.append(ans[nsrc * 2 + i]) # calculate best-fit model y = (OBJy[i] - mean(DATy)) / cdelt1p[0] x = (OBJx[i] - mean(DATx)) / cdelt2p[0] prfTmp = shift(prf, [y, x], order=3, mode='constant') prfTmp = prfTmp[PRFy0:PRFy0 + prfDimY, PRFx0:PRFx0 + prfDimX] PRFmod = PRFmod + prfTmp * flux[i] wx = 1.0 wy = 1.0 angle = 0 b = 0.0 # write out best fit parameters if verbose: txt = 'Flux = %10.2f e-/s ' % flux[i] txt += 'X = %9.4f pix ' % OBJx[i] txt += 'Y = %9.4f pix ' % OBJy[i] kepmsg.log(logfile, txt, True) if background: bterms = border + 1 if bterms == 1: b = ans[nsrc * 3] else: bcoeff = array([ ans[nsrc * 3:nsrc * 3 + bterms], ans[nsrc * 3 + bterms:nsrc * 3 + bterms * 2] ]) bkg = kepfunc.polyval2d(xx, yy, bcoeff) b = nanmean(bkg.reshape(bkg.size)) txt = '\n Mean background = %.2f e-/s' % b if verbose and background: kepmsg.log(logfile, txt, True) if focus: wx = ans[-3] wy = ans[-2] angle = ans[-1] if verbose and focus: if not background: kepmsg.log(logfile, '', True) kepmsg.log(logfile, ' X/Y focus factors = %.3f/%.3f' % (wx, wy), True) kepmsg.log(logfile, 'PRF rotation angle = %.2f deg' % angle, True) # measure flux fraction and contamination if status == 0: PRFall = kepfunc.PRF2DET(flux, OBJx, OBJy, DATx, DATy, wx, wy, angle, splineInterpolation) PRFone = kepfunc.PRF2DET([flux[0]], [OBJx[0]], [OBJy[0]], DATx, DATy, wx, wy, angle, splineInterpolation) # constuct model PRF in detector coordinates if status == 0: PRFfit = PRFall + 0.0 if background and bterms == 1: PRFfit = PRFall + b if background and bterms > 1: PRFfit = PRFall + bkg # calculate residual of DATA - FIT if status == 0: PRFres = DATimg - PRFfit FLUXres = numpy.nansum(PRFres) / npix # calculate the sum squared difference between data and model if status == 0: Pearson = abs(numpy.nansum(numpy.square(DATimg - PRFfit) / PRFfit)) Chi2 = numpy.nansum( numpy.square(DATimg - PRFfit) / numpy.square(ERRimg)) DegOfFreedom = npix - len(guess) - 1 if verbose: try: kepmsg.log(logfile, '\n Residual flux = %.2f e-/s' % FLUXres, True) kepmsg.log( logfile, 'Pearson\'s chi^2 test = %d for %d dof' % (Pearson, DegOfFreedom), True) except: pass kepmsg.log( logfile, ' Chi^2 test = %d for %d dof' % (Chi2, DegOfFreedom), True) result = np.array([flux[0], OBJx[0], OBJy[0]]) return result
def kepprf(infile,plotfile,rownum,columns,rows,fluxes,border,background,focus,prfdir,xtol,ftol, imscale,colmap,plt,verbose,logfile,status,cmdLine=False): # input arguments print "... input arguments" status = 0 seterr(all="ignore") # log the call print "... logging the call" hashline = '----------------------------------------------------------------------------' kepmsg.log(logfile,hashline,verbose) call = 'KEPPRF -- ' call += 'infile='+infile+' ' call += 'plotfile='+plotfile+' ' call += 'rownum='+str(rownum)+' ' call += 'columns='+columns+' ' call += 'rows='+rows+' ' call += 'fluxes='+fluxes+' ' call += 'border='+str(border)+' ' bground = 'n' if (background): bground = 'y' call += 'background='+bground+' ' focs = 'n' if (focus): focs = 'y' call += 'focus='+focs+' ' call += 'prfdir='+prfdir+' ' call += 'xtol='+str(xtol)+' ' call += 'ftol='+str(xtol)+' ' call += 'imscale='+imscale+' ' call += 'colmap='+colmap+' ' plotit = 'n' if (plt): plotit = 'y' call += 'plot='+plotit+' ' chatter = 'n' if (verbose): chatter = 'y' call += 'verbose='+chatter+' ' call += 'logfile='+logfile kepmsg.log(logfile,call+'\n',verbose) # test log file logfile = kepmsg.test(logfile) # start time print "... starting kepler time" kepmsg.clock('KEPPRF started at',logfile,verbose) # reference color map if colmap == 'browse': status = cmap_plot(cmdLine) # construct inital guess vector for fit print " status = "+str(status) print "... initial guess" if status == 0: guess = [] try: f = fluxes.strip().split(',') x = columns.strip().split(',') y = rows.strip().split(',') for i in xrange(len(f)): f[i] = float(f[i]) except: f = fluxes x = columns y = rows nsrc = len(f) for i in xrange(nsrc): try: guess.append(float(f[i])) except: message = 'ERROR -- KEPPRF: Fluxes must be floating point numbers' status = kepmsg.err(logfile,message,verbose) if status == 0: if len(x) != nsrc or len(y) != nsrc: message = 'ERROR -- KEPFIT:FITMULTIPRF: Guesses for rows, columns and ' message += 'fluxes must have the same number of sources' status = kepmsg.err(logfile,message,verbose) if status == 0: for i in xrange(nsrc): try: guess.append(float(x[i])) except: message = 'ERROR -- KEPPRF: Columns must be floating point numbers' status = kepmsg.err(logfile,message,verbose) if status == 0: for i in xrange(nsrc): try: guess.append(float(y[i])) except: message = 'ERROR -- KEPPRF: Rows must be floating point numbers' status = kepmsg.err(logfile,message,verbose) if status == 0 and background: if border == 0: guess.append(0.0) else: for i in range((border+1)*2): guess.append(0.0) if status == 0 and focus: guess.append(1.0); guess.append(1.0); guess.append(0.0) # open TPF FITS file print "... open tpf file" if status == 0: try: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, barytime, status = \ kepio.readTPF(infile,'TIME',logfile,verbose) except: message = 'ERROR -- KEPPRF: is %s a Target Pixel File? ' % infile status = kepmsg.err(logfile,message,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, tcorr, status = \ kepio.readTPF(infile,'TIMECORR',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, cadno, status = \ kepio.readTPF(infile,'CADENCENO',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, fluxpixels, status = \ kepio.readTPF(infile,'FLUX',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, errpixels, status = \ kepio.readTPF(infile,'FLUX_ERR',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, qual, status = \ kepio.readTPF(infile,'QUALITY',logfile,verbose) # read mask defintion data from TPF file print "... read mask definition" if status == 0: maskimg, pixcoord1, pixcoord2, status = kepio.readMaskDefinition(infile,logfile,verbose) npix = numpy.size(numpy.nonzero(maskimg)[0]) # print target data if status == 0 and verbose: print '' print ' KepID: %s' % kepid print ' RA (J2000): %s' % ra print 'Dec (J2000): %s' % dec print ' KepMag: %s' % kepmag print ' SkyGroup: %2s' % skygroup print ' Season: %2s' % str(season) print ' Channel: %2s' % channel print ' Module: %2s' % module print ' Output: %1s' % output print '' # is this a good row with finite timestamp and pixels? if status == 0: if not numpy.isfinite(barytime[rownum-1]) or numpy.nansum(fluxpixels[rownum-1,:]) == numpy.nan: message = 'ERROR -- KEPFIELD: Row ' + str(rownum) + ' is a bad quality timestamp' status = kepmsg.err(logfile,message,verbose) # construct input pixel image if status == 0: flux = fluxpixels[rownum-1,:] ferr = errpixels[rownum-1,:] DATx = arange(column,column+xdim) DATy = arange(row,row+ydim) # image scale and intensity limits of pixel data if status == 0: n = 0 DATimg = empty((ydim,xdim)) ERRimg = empty((ydim,xdim)) for i in range(ydim): for j in range(xdim): DATimg[i,j] = flux[n] ERRimg[i,j] = ferr[n] n += 1 # determine suitable PRF calibration file if status == 0: if int(module) < 10: prefix = 'kplr0' else: prefix = 'kplr' prfglob = prfdir + '/' + prefix + str(module) + '.' + str(output) + '*' + '_prf.fits' try: prffile = glob.glob(prfglob)[0] except: message = 'ERROR -- KEPPRF: No PRF file found in ' + prfdir status = kepmsg.err(logfile,message,verbose) # read PRF images if status == 0: prfn = [0,0,0,0,0] crpix1p = numpy.zeros((5),dtype='float32') crpix2p = numpy.zeros((5),dtype='float32') crval1p = numpy.zeros((5),dtype='float32') crval2p = numpy.zeros((5),dtype='float32') cdelt1p = numpy.zeros((5),dtype='float32') cdelt2p = numpy.zeros((5),dtype='float32') for i in range(5): prfn[i], crpix1p[i], crpix2p[i], crval1p[i], crval2p[i], cdelt1p[i], cdelt2p[i], status \ = kepio.readPRFimage(prffile,i+1,logfile,verbose) PRFx = arange(0.5,shape(prfn[0])[1]+0.5) PRFy = arange(0.5,shape(prfn[0])[0]+0.5) PRFx = (PRFx - size(PRFx) / 2) * cdelt1p[0] PRFy = (PRFy - size(PRFy) / 2) * cdelt2p[0] # interpolate the calibrated PRF shape to the target position if status == 0: prf = zeros(shape(prfn[0]),dtype='float32') prfWeight = zeros((5),dtype='float32') for i in xrange(5): prfWeight[i] = sqrt((column - crval1p[i])**2 + (row - crval2p[i])**2) if prfWeight[i] == 0.0: prfWeight[i] = 1.0e6 prf = prf + prfn[i] / prfWeight[i] prf = prf / nansum(prf) prf = prf / cdelt1p[0] / cdelt2p[0] # location of the data image centered on the PRF image (in PRF pixel units) if status == 0: prfDimY = int(ydim / cdelt1p[0]) prfDimX = int(xdim / cdelt2p[0]) PRFy0 = (shape(prf)[0] - prfDimY) / 2 PRFx0 = (shape(prf)[1] - prfDimX) / 2 # interpolation function over the PRF if status == 0: splineInterpolation = scipy.interpolate.RectBivariateSpline(PRFx,PRFy,prf) # construct mesh for background model if status == 0 and background: bx = numpy.arange(1.,float(xdim+1)) by = numpy.arange(1.,float(ydim+1)) xx, yy = numpy.meshgrid(numpy.linspace(bx.min(), bx.max(), xdim), numpy.linspace(by.min(), by.max(), ydim)) # fit PRF model to pixel data if status == 0: start = time.time() if focus and background: args = (DATx,DATy,DATimg,nsrc,border,xx,yy,PRFx,PRFy,splineInterpolation) ans = fmin_powell(kepfunc.PRFwithFocusAndBackground,guess,args=args,xtol=xtol, ftol=ftol,disp=False) elif focus and not background: args = (DATx,DATy,DATimg,nsrc,PRFx,PRFy,splineInterpolation) ans = fmin_powell(kepfunc.PRFwithFocus,guess,args=args,xtol=xtol, ftol=ftol,disp=False) elif background and not focus: args = (DATx,DATy,DATimg,nsrc,border,xx,yy,splineInterpolation) ans = fmin_powell(kepfunc.PRFwithBackground,guess,args=args,xtol=xtol, ftol=ftol,disp=False) else: args = (DATx,DATy,DATimg,splineInterpolation) ans = fmin_powell(kepfunc.PRF,guess,args=args,xtol=xtol, ftol=ftol,disp=False) print 'Convergence time = %.2fs\n' % (time.time() - start) # pad the PRF data if the PRF array is smaller than the data array if status == 0: flux = []; OBJx = []; OBJy = [] PRFmod = numpy.zeros((prfDimY,prfDimX)) if PRFy0 < 0 or PRFx0 < 0.0: PRFmod = numpy.zeros((prfDimY,prfDimX)) superPRF = zeros((prfDimY+1,prfDimX+1)) superPRF[abs(PRFy0):abs(PRFy0)+shape(prf)[0],abs(PRFx0):abs(PRFx0)+shape(prf)[1]] = prf prf = superPRF * 1.0 PRFy0 = 0 PRFx0 = 0 # rotate the PRF model around its center if focus: angle = ans[-1] prf = rotate(prf,-angle,reshape=False,mode='nearest') # iterate through the sources in the best fit PSF model for i in range(nsrc): flux.append(ans[i]) OBJx.append(ans[nsrc+i]) OBJy.append(ans[nsrc*2+i]) # calculate best-fit model y = (OBJy[i]-mean(DATy)) / cdelt1p[0] x = (OBJx[i]-mean(DATx)) / cdelt2p[0] prfTmp = shift(prf,[y,x],order=1,mode='constant') prfTmp = prfTmp[PRFy0:PRFy0+prfDimY,PRFx0:PRFx0+prfDimX] PRFmod = PRFmod + prfTmp * flux[i] wx = 1.0 wy = 1.0 angle = 0 b = 0.0 # write out best fit parameters if verbose: txt = 'Flux = %10.2f e-/s ' % flux[i] txt += 'X = %9.4f pix ' % OBJx[i] txt += 'Y = %9.4f pix ' % OBJy[i] kepmsg.log(logfile,txt,True) if verbose and background: bterms = border + 1 if bterms == 1: b = ans[nsrc*3] else: bcoeff = array([ans[nsrc*3:nsrc*3+bterms],ans[nsrc*3+bterms:nsrc*3+bterms*2]]) bkg = kepfunc.polyval2d(xx,yy,bcoeff) b = nanmean(bkg.reshape(bkg.size)) txt = '\n Mean background = %.2f e-/s' % b kepmsg.log(logfile,txt,True) if focus: wx = ans[-3] wy = ans[-2] angle = ans[-1] if verbose and focus: if not background: kepmsg.log(logfile,'',True) kepmsg.log(logfile,' X/Y focus factors = %.3f/%.3f' % (wx,wy),True) kepmsg.log(logfile,'PRF rotation angle = %.2f deg' % angle,True) # constuct model PRF in detector coordinates if status == 0: PRFfit = kepfunc.PRF2DET(flux,OBJx,OBJy,DATx,DATy,wx,wy,angle,splineInterpolation) if background and bterms == 1: PRFfit = PRFfit + b if background and bterms > 1: PRFfit = PRFfit + bkg # calculate residual of DATA - FIT if status == 0: PRFres = DATimg - PRFfit FLUXres = numpy.nansum(PRFres) # calculate the sum squared difference between data and model if status == 0: Pearson = abs(numpy.nansum(numpy.square(DATimg - PRFfit) / PRFfit)) Chi2 = numpy.nansum(numpy.square(DATimg - PRFfit) / numpy.square(ERRimg)) DegOfFreedom = npix - len(guess) try: kepmsg.log(logfile,'\nResidual flux = %.6f e-/s' % FLUXres,True) kepmsg.log(logfile,'Pearson\'s chi^2 test = %d for %d dof' % (Pearson,DegOfFreedom),True) except: pass # kepmsg.log(logfile,'Chi^2 test = %d for %d dof' % (Chi2,DegOfFreedom),True) # image scale and intensity limits for plotting images if status == 0: imgdat_pl, zminfl, zmaxfl = kepplot.intScale2D(DATimg,imscale) imgprf_pl, zminpr, zmaxpr = kepplot.intScale2D(PRFmod,imscale) imgfit_pl, zminfi, zmaxfi = kepplot.intScale2D(PRFfit,imscale) imgres_pl, zminre, zmaxre = kepplot.intScale2D(PRFres,imscale) if imscale == 'linear': zmaxpr *= 0.9 elif imscale == 'logarithmic': print zminpr,zmaxpr,numpy.max(zmaxpr) zmaxpr = numpy.max(zmaxpr) zminpr = zmaxpr / 2 # plot style if status == 0: try: params = {'backend': 'png', 'axes.linewidth': 2.5, 'axes.labelsize': 24, 'axes.font': 'sans-serif', 'axes.fontweight' : 'bold', 'text.fontsize': 12, 'legend.fontsize': 12, 'xtick.labelsize': 10, 'ytick.labelsize': 10} pylab.rcParams.update(params) except: pass pylab.figure(figsize=[10,10]) pylab.clf() plotimage(imgdat_pl,zminfl,zmaxfl,1,row,column,xdim,ydim,0.06,0.52,'flux',colmap) plotimage(imgprf_pl,zminpr,zmaxpr,2,row,column,xdim,ydim,0.52,0.52,'model',colmap) kepplot.borders(maskimg,xdim,ydim,pixcoord1,pixcoord2,1,'b','--',0.5) kepplot.borders(maskimg,xdim,ydim,pixcoord1,pixcoord2,2,'b','-',3.0) plotimage(imgfit_pl,zminfl,zmaxfl,3,row,column,xdim,ydim,0.06,0.06,'fit',colmap) plotimage(imgres_pl,zminfl,zmaxfl,4,row,column,xdim,ydim,0.52,0.06,'residual',colmap) # render plot if status == 0 and len(plotfile) > 0 and plotfile.lower() != 'none': pylab.savefig(plotfile) if status == 0 and plt: if cmdLine: pylab.show(block=True) else: pylab.ion() pylab.plot([]) pylab.ioff() # stop time kepmsg.clock('\nKEPPRF ended at',logfile,verbose) return
def kepdeltapix(infile,nexp,columns,rows,fluxes,prfdir,interpolation,tolerance,fittype,imscale, colmap,verbose,logfile,status,cmdLine=False): # input arguments status = 0 seterr(all="ignore") # log the call hashline = '----------------------------------------------------------------------------' kepmsg.log(logfile,hashline,verbose) call = 'KEPDELTAPIX -- ' call += 'infile='+infile+' ' call += 'nexp='+str(nexp)+' ' call += 'columns='+columns+' ' call += 'rows='+rows+' ' call += 'fluxes='+fluxes+' ' call += 'prfdir='+prfdir+' ' call += 'interpolation='+interpolation+' ' call += 'tolerance='+str(tolerance)+' ' call += 'fittype='+str(fittype)+' ' call += 'imscale='+imscale+' ' call += 'colmap='+colmap+' ' chatter = 'n' if (verbose): chatter = 'y' call += 'verbose='+chatter+' ' call += 'logfile='+logfile kepmsg.log(logfile,call+'\n',verbose) # test log file logfile = kepmsg.test(logfile) # start time kepmsg.clock('KEPDELTAPIX started at',logfile,verbose) # reference color map if colmap == 'browse': status = cmap_plot(cmdLine) # open TPF FITS file if status == 0: try: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, barytime, status = \ kepio.readTPF(infile,'TIME',logfile,verbose) except: message = 'ERROR -- KEPDELTAPIX: is %s a Target Pixel File? ' % infile status = kepmsg.err(logfile,message,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, tcorr, status = \ kepio.readTPF(infile,'TIMECORR',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, cadno, status = \ kepio.readTPF(infile,'CADENCENO',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, fluxpixels, status = \ kepio.readTPF(infile,'FLUX',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, errpixels, status = \ kepio.readTPF(infile,'FLUX_ERR',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, qual, status = \ kepio.readTPF(infile,'QUALITY',logfile,verbose) # print target data if status == 0 and verbose: print '' print ' KepID: %s' % kepid print ' RA (J2000): %s' % ra print 'Dec (J2000): %s' % dec print ' KepMag: %s' % kepmag print ' SkyGroup: %2s' % skygroup print ' Season: %2s' % str(season) print ' Channel: %2s' % channel print ' Module: %2s' % module print ' Output: %1s' % output print '' # determine suitable PRF calibration file if status == 0: if int(module) < 10: prefix = 'kplr0' else: prefix = 'kplr' prfglob = prfdir + '/' + prefix + str(module) + '.' + str(output) + '*' + '_prf.fits' try: prffile = glob.glob(prfglob)[0] except: message = 'ERROR -- KEPDELTAPIX: No PRF file found in ' + prfdir status = kepmsg.err(logfile,message,verbose) # read PRF images if status == 0: prfn = [0,0,0,0,0] crpix1p = numpy.zeros((5),dtype='float32') crpix2p = numpy.zeros((5),dtype='float32') crval1p = numpy.zeros((5),dtype='float32') crval2p = numpy.zeros((5),dtype='float32') cdelt1p = numpy.zeros((5),dtype='float32') cdelt2p = numpy.zeros((5),dtype='float32') for i in range(5): prfn[i], crpix1p[i], crpix2p[i], crval1p[i], crval2p[i], cdelt1p[i], cdelt2p[i], status \ = kepio.readPRFimage(prffile,i+1,logfile,verbose) # choose rows in the TPF table at random if status == 0: i = 0 rownum = [] while i < nexp: work = int(random.random() * len(barytime)) if numpy.isfinite(barytime[work]) and numpy.isfinite(fluxpixels[work,ydim*xdim/2]): rownum.append(work) i += 1 # construct input pixel image if status == 0: fscat = numpy.empty((len(fluxes),nexp),dtype='float32') xscat = numpy.empty((len(columns),nexp),dtype='float32') yscat = numpy.empty((len(rows),nexp),dtype='float32') for irow in range(nexp): flux = fluxpixels[rownum[irow],:] # image scale and intensity limits of pixel data if status == 0: flux_pl, zminfl, zmaxfl = kepplot.intScale1D(flux,imscale) n = 0 imgflux_pl = empty((ydim,xdim)) for i in range(ydim): for j in range(xdim): imgflux_pl[i,j] = flux_pl[n] n += 1 # fit PRF model to pixel data if status == 0: start = time.time() f,y,x,prfMod,prfFit,prfRes = kepfit.fitMultiPRF(flux,ydim,xdim,column,row,prfn,crval1p, crval2p,cdelt1p,cdelt2p,interpolation,tolerance,fluxes,columns,rows,fittype, verbose,logfile) if verbose: print '\nConvergence time = %.1fs' % (time.time() - start) # best fit parameters if status == 0: for i in range(len(f)): fscat[i,irow] = f[i] xscat[i,irow] = x[i] yscat[i,irow] = y[i] # replace starting guess with previous fit parameters if status == 0: fluxes = copy(f) columns = copy(x) rows = copy(y) # mean and rms results if status == 0: fmean = []; fsig = [] xmean = []; xsig = [] ymean = []; ysig = [] for i in range(len(f)): fmean.append(numpy.mean(fscat[i,:])) xmean.append(numpy.mean(xscat[i,:])) ymean.append(numpy.mean(yscat[i,:])) fsig.append(numpy.std(fscat[i,:])) xsig.append(numpy.std(xscat[i,:])) ysig.append(numpy.std(yscat[i,:])) txt = 'Flux = %10.2f e-/s ' % fmean[-1] txt += 'X = %7.4f +/- %6.4f pix ' % (xmean[-1], xsig[i]) txt += 'Y = %7.4f +/- %6.4f pix' % (ymean[-1], ysig[i]) kepmsg.log(logfile,txt,True) # output results for kepprfphot if status == 0: txt1 = 'columns=0.0' txt2 = ' rows=0.0' for i in range(1,len(f)): txt1 += ',%.4f' % (xmean[i] - xmean[0]) txt2 += ',%.4f' % (ymean[i] - ymean[0]) kepmsg.log(logfile,'\nkepprfphot input fields:',True) kepmsg.log(logfile,txt1,True) kepmsg.log(logfile,txt2,True) # image scale and intensity limits for PRF model image if status == 0: imgprf_pl, zminpr, zmaxpr = kepplot.intScale2D(prfMod,imscale) # image scale and intensity limits for PRF fit image if status == 0: imgfit_pl, zminfi, zmaxfi = kepplot.intScale2D(prfFit,imscale) # image scale and intensity limits for data - fit residual if status == 0: imgres_pl, zminre, zmaxre = kepplot.intScale2D(prfRes,imscale) # plot style if status == 0: try: params = {'backend': 'png', 'axes.linewidth': 2.5, 'axes.labelsize': 24, 'axes.font': 'sans-serif', 'axes.fontweight' : 'bold', 'text.fontsize': 12, 'legend.fontsize': 12, 'xtick.labelsize': 10, 'ytick.labelsize': 10} pylab.rcParams.update(params) except: pass pylab.figure(figsize=[10,10]) pylab.clf() plotimage(imgflux_pl,zminfl,zmaxfl,1,row,column,xdim,ydim,0.06,0.52,'flux',colmap) plotimage(imgfit_pl,zminfl,zmaxfl,3,row,column,xdim,ydim,0.06,0.06,'fit',colmap) plotimage(imgres_pl,zminfl,zmaxfl,4,row,column,xdim,ydim,0.52,0.06,'residual',colmap) plotimage(imgprf_pl,zminpr,zmaxpr*0.9,2,row,column,xdim,ydim,0.52,0.52,'model',colmap) for i in range(len(f)): pylab.plot(xscat[i,:],yscat[i,:],'o',color='k') # Plot creep of target position over time, relative to the central source # barytime0 = float(int(barytime[0] / 100) * 100.0) # barytime -= barytime0 # xlab = 'BJD $-$ %d' % barytime0 # xmin = numpy.nanmin(barytime) # xmax = numpy.nanmax(barytime) # y1min = numpy.nanmin(data) # y1max = numpy.nanmax(data) # xr = xmax - xmin # yr = ymax - ymin # barytime = insert(barytime,[0],[barytime[0]]) # barytime = append(barytime,[barytime[-1]]) # data = insert(data,[0],[0.0]) # data = append(data,0.0) # # pylab.figure(2,figsize=[10,10]) # pylab.clf() # ax = pylab.subplot(211) # pylab.subplots_adjust(0.1,0.5,0.88,0.42) # pylab.gca().xaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) # pylab.gca().yaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) # labels = ax.get_yticklabels() # setp(labels, 'rotation', 90, fontsize=ticksize) # for i in range(1,len(f)): # pylab.plot(rownum,xscat[i,:]-xscat[0,:],'o') # pylab.ylabel('$\Delta$Columns', {'color' : 'k'}) # ax = pylab.subplot(211) # pylab.subplots_adjust(0.1,0.1,0.88,0.42) # pylab.gca().xaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) # pylab.gca().yaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) # labels = ax.get_yticklabels() # setp(labels, 'rotation', 90, fontsize=ticksize) # for i in range(1,len(f)): # pylab.plot(rownum,yscat[i,:]-yscat[0,:],'o') # pylab.xlim(xmin-xr*0.01,xmax+xr*0.01) # if ymin-yr*0.01 <= 0.0 or fullrange: # pylab.ylim(1.0e-10,ymax+yr*0.01) # else: # pylab.ylim(ymin-yr*0.01,ymax+yr*0.01) # pylab.ylabel('$\Delta$Rows', {'color' : 'k'}) # pylab.xlabel(xlab, {'color' : 'k'}) # render plot if status == 0: if cmdLine: pylab.show(block=True) else: pylab.ion() pylab.plot([]) pylab.ioff() # stop time kepmsg.clock('\nKEPDELTAPIX ended at',logfile,verbose) return
def kepfake(outfile,prfdir,module,output,column,row,kepmag,background,xdim,ydim, clobber,verbose,logfile,status,cmdLine=False): # input arguments status = 0 seterr(all="ignore") # log the call hashline = '----------------------------------------------------------------------------' kepmsg.log(logfile,hashline,verbose) call = 'KEPFAKE -- ' call += 'outfile='+outfile+' ' call += 'prfdir='+prfdir+' ' call += 'module='+str(module)+' ' call += 'output='+str(output)+' ' call += 'column='+str(column)+' ' call += 'row='+str(row)+' ' call += 'kepmag='+str(kepmag)+' ' call += 'background='+str(background)+' ' call += 'xdim='+str(xdim)+' ' call += 'ydim='+str(ydim)+' ' clob = 'n' if (clobber): clob = 'y' call += 'clobber='+clob+' ' chatter = 'n' if (verbose): chatter = 'y' call += 'verbose='+chatter+' ' call += 'logfile='+logfile kepmsg.log(logfile,call+'\n',verbose) # test log file logfile = kepmsg.test(logfile) # plot style if status == 0: try: params = {'backend': 'png', 'axes.linewidth': 2.5, 'axes.labelsize': 24, 'axes.font': 'sans-serif', 'axes.fontweight' : 'bold', 'text.fontsize': 12, 'legend.fontsize': 12, 'xtick.labelsize': 10, 'ytick.labelsize': 10} pylab.rcParams.update(params) except: pass pylab.figure(figsize=[12,12]) pylab.clf() # start time kepmsg.clock('KEPFAKE started at',logfile,verbose) # clobber output file if status == 0: if clobber: status = kepio.clobber(outfile,logfile,verbose) if kepio.fileexists(outfile): message = 'ERROR -- KEPPRFPHOT: ' + outfile + ' exists. Use --clobber' status = kepmsg.err(logfile,message,verbose) # Create time-tagged arrays if status == 0: nobs = 192 time = zeros((nobs)) timecorr = zeros((nobs)) cadenceno = zeros((nobs)) raw_cnts = zeros((nobs,ydim,xdim)) flux = zeros((nobs,ydim,xdim)) flux_err = zeros((nobs,ydim,xdim)) flux_bkg = zeros((nobs,ydim,xdim)) flux_bkg_err = zeros((nobs,ydim,xdim)) cosmic_rays = zeros((nobs,ydim,xdim)) quality = zeros((nobs)) pos_corr1 = zeros((nobs)) pos_corr2 = zeros((nobs)) # Create aperture bit mqp if status == 0: aperture = ones((ydim,xdim)) * 3.0 # determine suitable PRF calibration file if status == 0: if int(module) < 10: prefix = 'kplr0' else: prefix = 'kplr' prfglob = prfdir + '/' + prefix + str(module) + '.' + str(output) + '*' + '_prf.fits' try: prffile = glob.glob(prfglob)[0] except: message = 'ERROR -- KEPFAKE: No PRF file found in ' + prfdir status = kepmsg.err(logfile,message,verbose) # read PRF images if status == 0: prfn = [0,0,0,0,0] crpix1p = numpy.zeros((5),dtype='float32') crpix2p = numpy.zeros((5),dtype='float32') crval1p = numpy.zeros((5),dtype='float32') crval2p = numpy.zeros((5),dtype='float32') cdelt1p = numpy.zeros((5),dtype='float32') cdelt2p = numpy.zeros((5),dtype='float32') for i in range(5): prfn[i], crpix1p[i], crpix2p[i], crval1p[i], crval2p[i], cdelt1p[i], cdelt2p[i], status \ = kepio.readPRFimage(prffile,i+1,logfile,verbose) PRFx = arange(0.5,shape(prfn[0])[1]+0.5) PRFy = arange(0.5,shape(prfn[0])[0]+0.5) PRFx = (PRFx - size(PRFx) / 2) * cdelt1p[0] PRFy = (PRFy - size(PRFy) / 2) * cdelt2p[0] # interpolate the calibrated PRF shape to the target position if status == 0: prf = zeros(shape(prfn[0]),dtype='float32') prfWeight = zeros((5),dtype='float32') for i in xrange(5): prfWeight[i] = sqrt((column - crval1p[i])**2 + (row - crval2p[i])**2) if prfWeight[i] == 0.0: prfWeight[i] = 1.0e6 prf = prf + prfn[i] / prfWeight[i] prf = prf / nansum(prf) / cdelt1p[0] / cdelt2p[0] # interpolation function over the PRF if status == 0: splineInterpolation = scipy.interpolate.RectBivariateSpline(PRFx,PRFy,prf,kx=3,ky=3) # flux from target if status == 0: zeropoint = 33.227 kepflux = 10.0**((zeropoint - kepmag) / 2.5) # range of the output image in detector coordinates if status == 0: if xdim % 2 == 0: xdim += 1 if ydim % 2 == 0: ydim += 1 DATx = arange(round(column) - floor(xdim/2),round(column) + floor(xdim/2) + 1.0) DATy = arange(round(row) - floor(ydim/2),round(row) + floor(ydim/2) + 1.0) ax = pylab.axes([0.05,0.5,0.45,0.45]) pylab.imshow(log10(prf+0.001),aspect='auto',interpolation='nearest',origin='lower',cmap='jet', extent=(min(PRFx),max(PRFx),min(PRFy),max(PRFy))) pylab.plot([-100.,100.],[0.0,0.0],'k',ls='--') pylab.plot([0.0,0.0],[-100.,100.],'k',ls='--') pylab.xlim(min(PRFx),max(PRFx)) pylab.ylim(min(PRFy),max(PRFy)) ax = pylab.axes([0.5,0.5,0.45,0.45]) TMPx = arange(min(PRFx),max(PRFx),0.1) + floor(column) TMPy = arange(min(PRFy),max(PRFy),0.1) + floor(row) PRFfit = kepfunc.PRF2DET([kepflux],[column],[row],TMPx,TMPy,1.0,1.0,0.0,splineInterpolation) PRFfit = PRFfit + background pylab.imshow(log10(PRFfit),aspect='auto',interpolation='nearest',origin='lower',cmap='jet', extent=(min(TMPx),max(TMPx),min(TMPy),max(TMPy))) pylab.plot([column,column],[-100.,2000.],'k',ls='--') pylab.plot([-100.,2000.],[row,row],'k',ls='--') pylab.xlim(min(TMPx),max(TMPx)) pylab.ylim(min(TMPy),max(TMPy)) ax = pylab.axes([0.05,0.05,0.45,0.45]) TMPx = arange(min(PRFx),max(PRFx),0.5) + floor(column) TMPy = arange(min(PRFy),max(PRFy),0.5) + floor(row) PRFfit = kepfunc.PRF2DET([kepflux],[column],[row],TMPx,TMPy,1.0,1.0,0.0,splineInterpolation) PRFfit = PRFfit + background pylab.imshow(log10(PRFfit),aspect='auto',interpolation='nearest',origin='lower',cmap='jet', extent=(min(TMPx),max(TMPx),min(TMPy),max(TMPy))) pylab.plot([column,column],[-100.,2000.],'k',ls='--') pylab.plot([-100.,2000.],[row,row],'k',ls='--') pylab.xlim(min(TMPx),max(TMPx)) pylab.ylim(min(TMPy),max(TMPy)) ax = pylab.axes([0.5,0.05,0.45,0.45]) TMPx = arange(min(PRFx),max(PRFx+1.0),1.0) + floor(column) - 0.5 TMPy = arange(min(PRFy),max(PRFy+1.0),1.0) + floor(row) - 0.5 PRFfit = kepfunc.PRF2DET([kepflux],[column],[row],TMPx,TMPy,1.0,1.0,0.0,splineInterpolation) PRFfit = PRFfit + background pylab.imshow(log10(PRFfit),aspect='auto',interpolation='nearest',origin='lower',cmap='jet', extent=(min(TMPx)-0.5,max(TMPx)-0.5,min(TMPy)-0.5,max(TMPy)-0.5)) pylab.plot([column,column],[-100.,2000.],'k',ls='--') pylab.plot([-100.,2000.],[row,row],'k',ls='--') pylab.xlim(min(TMPx),max(TMPx)) pylab.ylim(min(TMPy),max(TMPy)) pylab.ion() pylab.plot([]) pylab.ioff() # sys.exit() # location of the data image centered on the PRF image (in PRF pixel units) if status == 0: prfDimY = int(ydim / cdelt1p[0]) prfDimX = int(xdim / cdelt2p[0]) PRFy0 = (shape(prf)[0] - prfDimY) / 2 PRFx0 = (shape(prf)[1] - prfDimX) / 2 # iterate over each exposure if status == 0: for i in range(nobs): # for i in range(1): # constuct model PRF in detector coordinates if status == 0: PRFfit = kepfunc.PRF2DET([kepflux],[column],[row],DATx,DATy,1.0,1.0,0.0,splineInterpolation) PRFfit = PRFfit + background # add noise to image if status == 0: for index,value in ndenumerate(PRFfit): PRFfit[index] += sqrt(value) * kepfunc.inv_normal_cummulative_function(random.random()) # populate output array if status == 0: time[i] = 1500.2 + float(i) * 0.020416667 cadenceno[i] = 10000 + i flux[i,:,:] = PRFfit flux_err[i,:,:] = sqrt(PRFfit) pylab.imshow(log10(PRFfit),aspect='auto',interpolation='nearest',origin='lower',cmap='jet', extent=(min(DATx),max(DATx),min(DATy),max(DATy))) pylab.ion() pylab.plot([]) pylab.ioff() # Create the outfile primary extension if status == 0: hdu0 = PrimaryHDU() hdu0.header.update('EXTNAME','PRIMARY','name of extension') hdu0.header.update('EXTEND',True,'file may contain standard extensions') hdu0.header.update('EXTVER',1.0,'extension version number') hdu0.header.update('ORIGIN','NASA/Ames','organization that generated this file') hdu0.header.update('DATE','2014-04-08','file creation date') hdu0.header.update('CREATOR','FluxExporter-91415','SW version used to create this file') hdu0.header.update('PROCVER',11.0,'processing script version') hdu0.header.update('FILEVER','COA','file format version') hdu0.header.update('TIMVERSN','OGIP/93-003','OGIP memo number for file format') hdu0.header.update('TELESCOP','Kepler','telescope') hdu0.header.update('INSTRUME','Kepler photometer','detector type') hdu0.header.update('OBJECT','KIC 12345678','string version of kepID') hdu0.header.update('KEPLERID',1234567,'unique Kepler target identifier') hdu0.header.update('CHANNEL',58,'CCD channel') hdu0.header.update('SKYGROUP',32,'roll-independent location of channel') hdu0.header.update('MODULE',17,'CCD module') hdu0.header.update('OUTPUT',2,'CCD output') hdu0.header.update('QUARTER',4,'mission quarter during which data was collected') hdu0.header.update('SEASON',2,'mission season during which data was collected') hdu0.header.update('DATA_REL',25,'version of data release notes describing data') hdu0.header.update('OBSMODE','long cadence','observing mode') hdu0.header.update('RADESYS','ICRS','reference frame of celestial coordinates') hdu0.header.update('RA_OBJ',0.0,'[deg] right ascension from KIC') hdu0.header.update('DEC_OBJ',0.0,'[deg] declination from KIC') hdu0.header.update('EQUINOX',2000.0,'equinox of celestial coordinate system') hdu0.header.update('PMRA',0.0,'[arcsec/yr] RA proper motion') hdu0.header.update('PMDEC',0.0,'[arcsec/yr] Dec proper motion') hdu0.header.update('PMTOTAL',0.0,'[arcsec/yr] total proper motion') hdu0.header.update('PARALLAX',0.0,'[arcsec] parallax') hdu0.header.update('GLON',0.0,'[deg] galactic longitude') hdu0.header.update('GLAT',0.0,'[deg] galactic latitude') hdu0.header.update('GMAG',kepmag,'[mag] SDSS g band magnitude from KIC') hdu0.header.update('RMAG',kepmag,'[mag] SDSS r band magnitude from KIC') hdu0.header.update('IMAG',kepmag,'[mag] SDSS i band magnitude from KIC') hdu0.header.update('ZMAG',kepmag,'[mag] SDSS z band magnitude from KIC') hdu0.header.update('D51MAG',kepmag,'[mag] D51 magnitude, from KIC') hdu0.header.update('JMAG',kepmag,'[mag] J band magnitude from 2MASS') hdu0.header.update('HMAG',kepmag,'[mag] H band magnitude from 2MASS') hdu0.header.update('KMAG',kepmag,'[mag] K band magnitude from 2MASS') hdu0.header.update('KEPMAG',kepmag,'[mag] Kepler magnitude (Kp) from KIC') hdu0.header.update('GRCOLOR',0.0,'[mag] (g-r) color, SDSS bands') hdu0.header.update('JKCOLOR',0.0,'[mag] (J-K) color, 2MASS bands') hdu0.header.update('GKCOLOR',0.0,'[mag] (g-K) color, SDSS g - 2MASS K') hdu0.header.update('TEFF',5000.0,'[K] effective temperature from KIC') hdu0.header.update('LOGG',4.5,'[cm/s2] log10 surface gravity from KIC') hdu0.header.update('FEH',0.0,'[log10([Fe/H])] metallicity from KIC') hdu0.header.update('EBMINUSV',0.0,'[mag] E(B-V) redenning from KIC') hdu0.header.update('AV',0.0,'[mag] A_v extinction from KIC') hdu0.header.update('RADIUS',1.0,'[solar radii] stellar radius from KIC') hdu0.header.update('TMINDEX',1117146912,'unique 2MASS catalog ID from KIC') hdu0.header.update('SCPID',1117146912,'unique SCP processing ID from KIC') hdulist = HDUList(hdu0) # create the outfile table extension if status == 0: eformat = str(ydim*xdim) + 'E' jformat = str(ydim*xdim) + 'J' kformat = str(ydim*xdim) + 'K' coldim = '(' + str(ydim) + ',' + str(ydim) + ')' col1 = Column(name='TIME',format='D',unit='BJD - 2454833',array=time) col2 = Column(name='TIMECORR',format='E',unit='d',array=timecorr) col3 = Column(name='CADENCENO',format='J',array=cadenceno) col4 = Column(name='RAW_CNTS',format=jformat,unit='count',dim=coldim,array=raw_cnts) col5 = Column(name='FLUX',format=eformat,unit='e-/s',dim=coldim,array=flux) col6 = Column(name='FLUX_ERR',format=eformat,unit='e-/s',dim=coldim,array=flux_err) col7 = Column(name='FLUX_BKG',format=eformat,unit='e-/s',dim=coldim,array=flux_bkg) col8 = Column(name='FLUX_BKG_ERR',format=eformat,unit='e-/s',dim=coldim,array=flux_bkg_err) col9 = Column(name='COSMIC_RAYS',format=eformat,unit='e-/s',dim=coldim,array=cosmic_rays) col10 = Column(name='QUALITY',format='J',array=quality) col11 = Column(name='POS_CORR1',format='E',unit='pixel',array=pos_corr1) col12 = Column(name='POS_CORR2',format='E',unit='pixel',array=pos_corr2) cols = ColDefs([col1,col2,col3,col4,col5,col6,col7,col8,col9,col10,col11,col12]) hdu1 = new_table(cols) hdu1.header.update('TTYPE1','TIME','column title: data time stamps') hdu1.header.update('TFORM1','D','data type: float64') hdu1.header.update('TUNIT1','BJD - 2454833','column units: barycenter corrected JD') hdu1.header.update('TDISP1','D13.7','column display format') hdu1.header.update('TTYPE2','TIMECORR','column title: barycentric correction') hdu1.header.update('TFORM2','E','column format: float32') hdu1.header.update('TUNIT2','d','column units: days') hdu1.header.update('TDISP2','D12.7','column display format') hdu1.header.update('TTYPE3','CADENCENO','column title: unique cadence number') hdu1.header.update('TFORM3','J','column format: signed integer32') hdu1.header.update('TTYPE4','RAW_CNTS','column title: raw pixel count') hdu1.header.update('TFORM4',jformat,'column format: signed integer32') hdu1.header.update('TDIM4',coldim,'column dimensions: pixel apeture array') hdu1.header.update('TUNIT4','count','column units: count') hdu1.header.update('TTYPE5','FLUX','column title: calibrated pixel flux') hdu1.header.update('TFORM5',eformat,'column format: float32') hdu1.header.update('TDIM5',coldim,'column dimensions: pixel apeture array') hdu1.header.update('TUNIT5','e-/s','column units: electrons per second') hdu1.header.update('TTYPE6','FLUX_ERR','column title: 1-sigma calibrated uncertainty') hdu1.header.update('TFORM6',eformat,'column format: float32') hdu1.header.update('TDIM6',coldim,'column dimensions: pixel apeture array') hdu1.header.update('TUNIT6','e-/s','column units: electrons per second (1-sigma)') hdu1.header.update('TTYPE7','FLUX_BKG','column title: calibrated background flux') hdu1.header.update('TFORM7',eformat,'column format: float32') hdu1.header.update('TDIM7',coldim,'column dimensions: pixel apeture array') hdu1.header.update('TUNIT7','e-/s','column units: electrons per second') hdu1.header.update('TTYPE8','FLUX_BKG_ERR','column title: 1-sigma cal. backgrnd uncertainty') hdu1.header.update('TFORM8',eformat,'column format: float32') hdu1.header.update('TDIM8',coldim,'column dimensions: pixel apeture array') hdu1.header.update('TUNIT8','e-/s','column units: electrons per second (1-sigma)') hdu1.header.update('TTYPE9','COSMIC_RAYS','column title: cosmic ray detections') hdu1.header.update('TFORM9',eformat,'column format: float32') hdu1.header.update('TDIM9',coldim,'column dimensions: pixel apeture array') hdu1.header.update('TUNIT9','e-/s','column units: electrons per second') hdu1.header.update('TTYPE10','QUALITY','column title: pixel quality flags') hdu1.header.update('TFORM10','J','column format: signed integer32') hdu1.header.update('TTYPE11','POS_CORR1','column title: col correction for vel. abbern') hdu1.header.update('TFORM11','E','column format: float32') hdu1.header.update('TUNIT11','pixel','column units: pixel') hdu1.header.update('TTYPE12','POS_CORR2','column title: row correction for vel. abbern') hdu1.header.update('TFORM12','E','column format: float32') hdu1.header.update('TUNIT12','pixel','column units: pixel') hdu1.header.update('WCAX4',2,'number of WCS axes') hdu1.header.update('1CTY4P','RAWX','right ascension coordinate type') hdu1.header.update('2CTY4P','RAWY','declination coordinate type') hdu1.header.update('1CRP4P',1,'[pixel] reference pixel along image axis 1') hdu1.header.update('2CRP4P',1,'[pixel] reference pixel along image axis 2') hdu1.header.update('1CRV4P',DATx[0],'[pixel] detector coordinate at reference pixel') hdu1.header.update('2CRV4P',DATy[0],'[pixel] detector coordinate at reference pixel') hdu1.header.update('1CUN4P','pixel','physical unit in column dimension') hdu1.header.update('2CUN4P','pixel','physical unit in row dimension') hdu1.header.update('1CDE4P',1.0,'[pixel] pixel scale in column dimension') hdu1.header.update('2CDE4P',1.0,'[pixel] pixel scale in row dimension') hdu1.header.update('1CTYP4','RA---TAN','right ascension coordinate type') hdu1.header.update('2CTYP4','DEC--TAN','declination coordinate type') hdu1.header.update('1CRPX4',int(xdim/2),'[pixel] reference pixel along image axis 1') hdu1.header.update('2CRPX4',int(ydim/2),'[pixel] reference pixel along image axis 2') hdu1.header.update('1CRVL4',294.94017,'[deg] right ascension at reference pixel') hdu1.header.update('2CRVL4',43.80033,'[deg] declination at reference pixel') hdu1.header.update('1CUNI4','deg','physical unit in column dimension') hdu1.header.update('2CUNI4','deg','physical unit in row dimension') hdu1.header.update('1CDLT4',-0.001106815552144,'[deg] pixel scale in RA dimension') hdu1.header.update('2CDLT4',0.001106815552144,'[deg] pixel scale in Dec dimension') hdu1.header.update('11PC4',0.46086006096337634,'linear transformation matrix element cos(th)') hdu1.header.update('12PC4',-0.8897046441865888,'linear transformation matrix element -sin(th)') hdu1.header.update('21PC4',0.8864170184391076,'linear transformation matrix element sin(th)') hdu1.header.update('22PC4',0.45860051653617395,'linear transformation matrix element cos(th)') hdu1.header.update('WCAX5',2,'number of WCS axes') hdu1.header.update('1CTY5P','RAWX','right ascension coordinate type') hdu1.header.update('2CTY5P','RAWY','declination coordinate type') hdu1.header.update('1CRP5P',1,'[pixel] reference pixel along image axis 1') hdu1.header.update('2CRP5P',1,'[pixel] reference pixel along image axis 2') hdu1.header.update('1CRV5P',DATx[0],'[pixel] detector coordinate at reference pixel') hdu1.header.update('2CRV5P',DATy[0],'[pixel] detector coordinate at reference pixel') hdu1.header.update('1CUN5P','pixel','physical unit in column dimension') hdu1.header.update('2CUN5P','pixel','physical unit in row dimension') hdu1.header.update('1CDE5P',1.0,'[pixel] pixel scale in column dimension') hdu1.header.update('2CDE5P',1.0,'[pixel] pixel scale in row dimension') hdu1.header.update('1CTYP5','RA---TAN','right ascension coordinate type') hdu1.header.update('2CTYP5','DEC--TAN','declination coordinate type') hdu1.header.update('1CRPX5',int(xdim/2),'[pixel] reference pixel along image axis 1') hdu1.header.update('2CRPX5',int(ydim/2),'[pixel] reference pixel along image axis 2') hdu1.header.update('1CRVL5',294.94017,'[deg] right ascension at reference pixel') hdu1.header.update('2CRVL5',43.80033,'[deg] declination at reference pixel [deg]') hdu1.header.update('1CUNI5','deg','physical unit in column dimension') hdu1.header.update('2CUNI5','deg','physical unit in row dimension') hdu1.header.update('1CDLT5',-0.001106815552144,'[deg] pixel scale in RA dimension') hdu1.header.update('2CDLT5',0.001106815552144,'[deg] pixel scale in Dec dimension') hdu1.header.update('11PC5',0.46086006096337634,'linear transformation matrix element cos(th)') hdu1.header.update('12PC5',-0.8897046441865888,'linear transformation matrix element -sin(th)') hdu1.header.update('21PC5',0.8864170184391076,'linear transformation matrix element sin(th)') hdu1.header.update('22PC5',0.45860051653617395,'linear transformation matrix element cos(th)') hdu1.header.update('WCAX6',2,'number of WCS axes') hdu1.header.update('1CTY6P','RAWX','right ascension coordinate type') hdu1.header.update('2CTY6P','RAWY','declination coordinate type') hdu1.header.update('1CRP6P',1,'[pixel] reference pixel along image axis 1') hdu1.header.update('2CRP6P',1,'[pixel] reference pixel along image axis 2') hdu1.header.update('1CRV6P',DATx[0],'[pixel] detector coordinate at reference pixel') hdu1.header.update('2CRV6P',DATy[0],'[pixel] detector coordinate at reference pixel') hdu1.header.update('1CUN6P','pixel','physical unit in column dimension') hdu1.header.update('2CUN6P','pixel','physical unit in row dimension') hdu1.header.update('1CDE6P',1.0,'[pixel] pixel scale in column dimension') hdu1.header.update('2CDE6P',1.0,'[pixel] pixel scale in row dimension') hdu1.header.update('1CTYP6','RA---TAN','right ascension coordinate type') hdu1.header.update('2CTYP6','DEC--TAN','declination coordinate type') hdu1.header.update('1CRPX6',int(xdim/2),'[pixel] reference pixel along image axis 1') hdu1.header.update('2CRPX6',int(ydim/2),'[pixel] reference pixel along image axis 2') hdu1.header.update('1CRVL6',294.94017,'[deg] right ascension at reference pixel') hdu1.header.update('2CRVL6',43.80033,'[deg] declination at reference pixel') hdu1.header.update('1CUNI6','deg','physical unit in column dimension') hdu1.header.update('2CUNI6','deg','physical unit in row dimension') hdu1.header.update('1CDLT6',-0.00110558987335788,'[deg] pixel scale in RA dimension') hdu1.header.update('2CDLT6',0.00110558987335788,'[deg] pixel scale in Dec dimension') hdu1.header.update('11PC6',0.46086006096337634,'linear transformation matrix element cos(th)') hdu1.header.update('12PC6',-0.8897046441865888,'linear transformation matrix element -sin(th)') hdu1.header.update('21PC6',0.8864170184391076,'linear transformation matrix element sin(th)') hdu1.header.update('22PC6',0.45860051653617395,'linear transformation matrix element cos(th)') hdu1.header.update('WCAX7',2,'number of WCS axes') hdu1.header.update('1CTY7P','RAWX','right ascension coordinate type') hdu1.header.update('2CTY7P','RAWY','declination coordinate type') hdu1.header.update('1CRP7P',1,'[pixel] reference pixel along image axis 1') hdu1.header.update('2CRP7P',1,'[pixel] reference pixel along image axis 2') hdu1.header.update('1CRV7P',DATx[0],'[pixel] detector coordinate at reference pixel') hdu1.header.update('2CRV7P',DATy[0],'[pixel] detector coordinate at reference pixel') hdu1.header.update('1CUN7P','pixel','physical unit in column dimension') hdu1.header.update('2CUN7P','pixel','physical unit in row dimension') hdu1.header.update('1CDE7P',1.0,'[pixel] pixel scale in column dimension') hdu1.header.update('2CDE7P',1.0,'[pixel] pixel scale in row dimension') hdu1.header.update('1CTYP7','RA---TAN','right ascension coordinate type') hdu1.header.update('2CTYP7','DEC--TAN','declination coordinate type') hdu1.header.update('1CRPX7',int(xdim/2),'[pixel] reference pixel along image axis 1') hdu1.header.update('2CRPX7',int(ydim/2),'[pixel] reference pixel along image axis 2') hdu1.header.update('1CRVL7',294.94017,'[deg] right ascension at reference pixel') hdu1.header.update('2CRVL7',43.80033,'[deg] declination at reference pixel') hdu1.header.update('1CUNI7','deg','physical unit in column dimension') hdu1.header.update('2CUNI7','deg','physical unit in row dimension') hdu1.header.update('1CDLT7',-0.00110558987335788,'[deg] pixel scale in RA dimension') hdu1.header.update('2CDLT7',0.00110558987335788,'[deg] pixel scale in Dec dimension') hdu1.header.update('11PC7',0.46086006096337634,'linear transformation matrix element cos(th)') hdu1.header.update('12PC7',-0.8897046441865888,'linear transformation matrix element -sin(th)') hdu1.header.update('21PC7',0.8864170184391076,'linear transformation matrix element sin(th)') hdu1.header.update('22PC7',0.45860051653617395,'linear transformation matrix element cos(th)') hdu1.header.update('WCAX8',2,'number of WCS axes') hdu1.header.update('1CTY8P','RAWX','right ascension coordinate type') hdu1.header.update('2CTY8P','RAWY','declination coordinate type') hdu1.header.update('1CRP8P',1,'[pixel] reference pixel along image axis 1') hdu1.header.update('2CRP8P',1,'[pixel] reference pixel along image axis 2') hdu1.header.update('1CRV8P',DATx[0],'[pixel] detector coordinate at reference pixel') hdu1.header.update('2CRV8P',DATy[0],'[pixel] detector coordinate at reference pixel') hdu1.header.update('1CUN8P','pixel','physical unit in column dimension') hdu1.header.update('2CUN8P','pixel','physical unit in row dimension') hdu1.header.update('1CDE8P',1.0,'[pixel] pixel scale in column dimension') hdu1.header.update('2CDE8P',1.0,'[pixel] pixel scale in row dimension') hdu1.header.update('1CTYP8','RA---TAN','right ascension coordinate type') hdu1.header.update('2CTYP8','DEC--TAN','declination coordinate type') hdu1.header.update('1CRPX8',int(xdim/2),'[pixel] reference pixel along image axis 1') hdu1.header.update('2CRPX8',int(ydim/2),'[pixel] reference pixel along image axis 2') hdu1.header.update('1CRVL8',294.94017,'[deg] right ascension at reference pixel') hdu1.header.update('2CRVL8',43.80033,'[deg] declination at reference pixel') hdu1.header.update('1CUNI8','deg','physical unit in column dimension') hdu1.header.update('2CUNI8','deg','physical unit in row dimension') hdu1.header.update('1CDLT8',-0.00110558987335788,'[deg] pixel scale in RA dimension') hdu1.header.update('2CDLT8',0.00110558987335788,'[deg] pixel scale in Dec dimension') hdu1.header.update('11PC8',0.46086006096337634,'linear transformation matrix element cos(th)') hdu1.header.update('12PC8',-0.8897046441865888,'linear transformation matrix element -sin(th)') hdu1.header.update('21PC8',0.8864170184391076,'linear transformation matrix element sin(th)') hdu1.header.update('22PC8',0.45860051653617395,'linear transformation matrix element cos(th)') hdu1.header.update('WCAX9',2,'number of WCS axes') hdu1.header.update('1CTY9P','RAWX','right ascension coordinate type') hdu1.header.update('2CTY9P','RAWY','declination coordinate type') hdu1.header.update('1CRP9P',1,'[pixel] reference pixel along image axis 1') hdu1.header.update('2CRP9P',1,'[pixel] reference pixel along image axis 2') hdu1.header.update('1CRV9P',DATx[0],'[pixel] detector coordinate at reference pixel') hdu1.header.update('2CRV9P',DATy[0],'[pixel] detector coordinate at reference pixel') hdu1.header.update('1CUN9P','pixel','physical unit in column dimension') hdu1.header.update('2CUN9P','pixel','physical unit in row dimension') hdu1.header.update('1CDE9P',1.0,'[pixel] pixel scale in column dimension') hdu1.header.update('2CDE9P',1.0,'[pixel] pixel scale in row dimension') hdu1.header.update('1CTYP9','RA---TAN','right ascension coordinate type') hdu1.header.update('2CTYP9','DEC--TAN','declination coordinate type') hdu1.header.update('1CRPX9',int(xdim/2),'[pixel] reference pixel along image axis 1') hdu1.header.update('2CRPX9',int(ydim/2),'[pixel] reference pixel along image axis 2') hdu1.header.update('1CRVL9',294.94017,'[deg] right ascension at reference pixel') hdu1.header.update('2CRVL9',43.80033,'[deg] declination at reference pixel') hdu1.header.update('1CUNI9','deg','physical unit in column dimension') hdu1.header.update('2CUNI9','deg','physical unit in row dimension') hdu1.header.update('1CDLT9',-0.00110558987335788,'[deg] pixel scale in RA dimension') hdu1.header.update('2CDLT9',0.00110558987335788,'[deg] pixel scale in Dec dimension') hdu1.header.update('11PC9',0.46086006096337634,'linear transformation matrix element cos(th)') hdu1.header.update('12PC9',-0.8897046441865888,'linear transformation matrix element -sin(th)') hdu1.header.update('21PC9',0.8864170184391076,'linear transformation matrix element sin(th)') hdu1.header.update('22PC9',0.45860051653617395,'linear transformation matrix element cos(th)') hdu1.header.update('WCAX10',2,'number of WCS axes') hdu1.header.update('1CTY10P','RAWX','right ascension coordinate type') hdu1.header.update('2CTY10P','RAWY','declination coordinate type') hdu1.header.update('1CRP10P',1,'[pixel] reference pixel along image axis 1') hdu1.header.update('2CRP10P',1,'[pixel] reference pixel along image axis 2') hdu1.header.update('1CRV10P',DATx[0],'[pixel] detector coordinate at reference pixel') hdu1.header.update('2CRV10P',DATy[0],'[pixel] detector coordinate at reference pixel') hdu1.header.update('1CUN10P','pixel','physical unit in column dimension') hdu1.header.update('2CUN10P','pixel','physical unit in row dimension') hdu1.header.update('1CDE10P',1.0,'[pixel] pixel scale in column dimension') hdu1.header.update('2CDE10P',1.0,'[pixel] pixel scale in row dimension') hdu1.header.update('1CTYP10','RA---TAN','right ascension coordinate type') hdu1.header.update('2CTYP10','DEC--TAN','declination coordinate type') hdu1.header.update('1CRPX10',int(xdim/2),'[pixel] reference pixel along image axis 1') hdu1.header.update('2CRPX10',int(ydim/2),'[pixel] reference pixel along image axis 2') hdu1.header.update('1CRVL10',294.94017,'[deg] right ascension at reference pixel') hdu1.header.update('2CRVL10',43.80033,'[deg] declination at reference pixel') hdu1.header.update('1CUNI10','deg','physical unit in column dimension') hdu1.header.update('2CUNI10','deg','physical unit in row dimension') hdu1.header.update('1CDLT10',-0.00110558987335788,'[deg] pixel scale in RA dimension') hdu1.header.update('2CDLT10',0.00110558987335788,'[deg] pixel scale in Dec dimension') hdu1.header.update('11PC10',0.46086006096337634,'linear transformation matrix element cos(th)') hdu1.header.update('12PC10',-0.8897046441865888,'linear transformation matrix element -sin(th)') hdu1.header.update('21PC10',0.8864170184391076,'linear transformation matrix element sin(th)') hdu1.header.update('22PC10',0.45860051653617395,'linear transformation matrix element cos(th)') hdu1.header.update('INHERIT',True,'inherit primary keywords') hdu1.header.update('EXTNAME','TARGETTABLES','name of extension') hdu1.header.update('EXTVER',1,'extension version number') hdu1.header.update('TELESCOP','Kepler','telescope') hdu1.header.update('INSTRUME','Kepler photometer','detector type') hdu1.header.update('OBJECT','KIC 12345678','string version of kepID') hdu1.header.update('KEPLERID',12345678,'unique Kepler target identifier') hdu1.header.update('RADESYS','ICRS','reference frame of celestial coordinates') hdu1.header.update('RA_OBJ',0.0,'[deg] right ascension from KIC') hdu1.header.update('DEC_OBJ',0.0,'[deg] declination from KIC') hdu1.header.update('EQUINOX',2000.0,'equinox of celestial coordinate system') hdu1.header.update('TIMEREF','SOLARSYSTEM','barycentric correction applied to times') hdu1.header.update('TASSIGN','SPACECRAFT','where time is assigned') hdu1.header.update('TIMESYS','TDB','time system is barycentric JD') hdu1.header.update('BJDREFI',2454833,'integer part of BJD reference date') hdu1.header.update('BJDREFF',0.0,'fraction of day in BJD reference date') hdu1.header.update('TIMEUNIT','d','time unit for TIME, TSTART and TSTOP') hdu1.header.update('TSTART',1500.0,'observation start time in JD - BJDREF') hdu1.header.update('TSTOP',1504.0,'observation stop time in JD - BJDREF') hdu1.header.update('LC_START',1500.0+54833.5,'observation start time in MJD') hdu1.header.update('LC_END',1504.0+54833.5,'observation stop time in MJD') hdu1.header.update('TELAPSE',93.0,'[d] TSTOP - TSTART') hdu1.header.update('LIVETIME',82.7273,'[d] TELAPSE multiplied by DEADC') hdu1.header.update('EXPOSURE',82.7273,'[d] time on source') hdu1.header.update('DEADC',0.909091,'deadtime correction') hdu1.header.update('TIMEPIXR',0.5,'bin time beginning=0 middle=0.5 end=1') hdu1.header.update('TIERRELA',5.78e-7,'[d] relative time error') hdu1.header.update('TIERABSO',5.78e-6,'[d] absolute time error') hdu1.header.update('INT_TIME',6.0198,'[s] photon accumulation time per frame') hdu1.header.update('READTIME',0.518948526144,'[s] readout time per frame') hdu1.header.update('FRAMETIM',6.53875,'[s] frame time (INT_TIME + READTIME)') hdu1.header.update('NUM_FRM',270,'number of frames per time stamp') hdu1.header.update('TIMEDEL',30.0/1440,'[d] time resolution of data') hdu1.header.update('DATE-OBS','2014-09-30T12:28:48.0','TSTART as UT calendar date') hdu1.header.update('DATE-END','2014-10-02T11:02:24.0','TSTOP as UT calendar date') hdu1.header.update('BACKAPP',True,'background is subtracted') hdu1.header.update('DEADAPP',False,'deadtime applied') hdu1.header.update('VIGNAPP',False,'vignetting or collimator correction applied') hdu1.header.update('GAIN',104.88,'[electrons/count] channel gain') hdu1.header.update('READNOIS',0.7845*104.88,'[electrons] read noise') hdu1.header.update('NREADOUT',276,'number of reads per cadence') hdu1.header.update('TIMSLICE',3,'time-slice readout sequence section') hdu1.header.update('MEANBLCK',738,'[count] FSW mean black level') hdulist.append(hdu1) # create the outfile image extension if status == 0: hdu2 = ImageHDU(aperture) hdu2.header.update('INHERIT',True,'inherit primary keywords') hdu2.header.update('EXTNAME','APERTURE','extension name') hdu2.header.update('EXTVER',1,'extension version number') hdu2.header.update('TELESCOP','Kepler','telescope') hdu2.header.update('INSTRUME','Kepler photometer','detector type') hdu2.header.update('OBJECT','KIC 12345678','string version of kepID') hdu2.header.update('KEPLERID',1234567,'unique Kepler target identifier') hdu2.header.update('RADESYS','ICRS','reference frame of celestial coordinates') hdu2.header.update('RA_OBJ',294.94017,'[deg] right ascension from KIC') hdu2.header.update('DEC_OBJ',43.80033,'[deg] declination from KIC') hdu2.header.update('EQUINOX',2000.0,'equinox of celestial coordinate system') hdu2.header.update('WCSAXES',2,'number of WCS axes') hdu2.header.update('CTYPE1P','RAWX','pixel coordinate type') hdu2.header.update('CTYPE2P','RAWY','pixel coordinate type') hdu2.header.update('CRPIX1P',1,'[pixel] reference pixel along image axis 1') hdu2.header.update('CRPIX2P',1,'[pixel] reference pixel along image axis 2') hdu2.header.update('CRVAL1P',DATx[0],'[pixel] column number at reference pixel') hdu2.header.update('CRVAL2P',DATy[0],'[pixel] row number at reference pixel') hdu2.header.update('CUNIT1P','pixel','physical unit in column dimension') hdu2.header.update('CUNIT2P','pixel','physical unit in row dimension') hdu2.header.update('CDELT1P',1.0,'[pixel] pixel scale along columns') hdu2.header.update('CDELT2P',1.0,'[pixel] pixel scale along rows') hdu2.header.update('CTYPE1','RA---TAN','right ascension coordinate type') hdu2.header.update('CTYPE2','DEC--TAN','declination coordinate type') hdu2.header.update('CRPIX1',int(xdim/2),'[pixel] reference pixel along image axis 1') hdu2.header.update('CRPIX2',int(ydim/2),'[pixel] reference pixel along image axis 2') hdu2.header.update('CRVAL1',294.94017,'right ascension at reference pixel [deg]') hdu2.header.update('CRVAL2',43.80033,'declination at reference pixel [deg]') hdu2.header.update('CUNIT1','deg','physical unit in column dimension') hdu2.header.update('CUNIT2','deg','physical unit in row dimension') hdu2.header.update('CDELT1',-0.001106815552144,'pixel scale in RA dimension') hdu2.header.update('CDELT2',0.001106815552144,'pixel scale in Dec dimension') hdu2.header.update('PC1_1',0.46086006096337634,'linear transformation matrix element cos(th)') hdu2.header.update('PC1_2',-0.8897046441865888,'linear transformation matrix element -sin(th)') hdu2.header.update('PC2_1',0.8864170184391076,'linear transformation matrix element sin(th)') hdu2.header.update('PC2_2',0.45860051653617395,'linear transformation matrix element cos(th)') hdulist.append(hdu2) # write output file if status == 0: hdulist.writeto(outfile,checksum=True) # stop time kepmsg.clock('\nKEPFAKE ended at',logfile,verbose) return
def kepprf(infile, columns, rows, fluxes, rownum=0, border=0, background=0, focus=0, prfdir='../KeplerPRF', xtol=1.e-6, ftol=1.e-6, imscale='linear', cmap='YlOrBr', lcolor='k', acolor='b', logfile='kepcrowd.log', CrowdTPF=np.nan, srcinfo=None, **kwargs): # log the call hashline = '----------------------------------------------------------------------------' kepmsg.log(logfile, hashline, True) call = 'KEPPRF -- ' call += 'infile=' + infile + ' ' call += 'rownum=' + str(rownum) + ' ' call += 'columns=' + columns + ' ' call += 'rows=' + rows + ' ' call += 'fluxes=' + fluxes + ' ' call += 'border=' + str(border) + ' ' bground = 'n' if (background): bground = 'y' call += 'background=' + bground + ' ' focs = 'n' if (focus): focs = 'y' call += 'focus=' + focs + ' ' call += 'prfdir=' + prfdir + ' ' call += 'xtol=' + str(xtol) + ' ' call += 'ftol=' + str(xtol) + ' ' call += 'logfile=' + logfile kepmsg.log(logfile, call + '\n', True) guess = [] try: f = fluxes.strip().split(',') x = columns.strip().split(',') y = rows.strip().split(',') for i in range(len(f)): f[i] = float(f[i]) except: f = fluxes x = columns y = rows nsrc = len(f) for i in range(nsrc): try: guess.append(float(f[i])) except: message = 'ERROR -- KEPPRF: Fluxes must be floating point numbers' kepmsg.err(logfile, message, True) return None if len(x) != nsrc or len(y) != nsrc: message = 'ERROR -- KEPFIT:FITMULTIPRF: Guesses for rows, columns and ' message += 'fluxes must have the same number of sources' kepmsg.err(logfile, message, True) return None for i in range(nsrc): try: guess.append(float(x[i])) except: message = 'ERROR -- KEPPRF: Columns must be floating point numbers' kepmsg.err(logfile, message, True) return None for i in range(nsrc): try: guess.append(float(y[i])) except: message = 'ERROR -- KEPPRF: Rows must be floating point numbers' kepmsg.err(logfile, message, True) return None if background: if border == 0: guess.append(0.0) else: for i in range((border + 1) * 2): guess.append(0.0) if focus: guess.append(1.0) guess.append(1.0) guess.append(0.0) # open TPF FITS file try: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, barytime, status = \ kepio.readTPF(infile,'TIME',logfile,True) except: message = 'ERROR -- KEPPRF: is %s a Target Pixel File? ' % infile kepmsg.err(logfile, message, True) return None kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, tcorr, status = \ kepio.readTPF(infile,'TIMECORR',logfile,True) kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, cadno, status = \ kepio.readTPF(infile,'CADENCENO',logfile,True) kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, fluxpixels, status = \ kepio.readTPF(infile,'FLUX',logfile,True) kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, errpixels, status = \ kepio.readTPF(infile,'FLUX_ERR',logfile,True) kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, qual, status = \ kepio.readTPF(infile,'QUALITY',logfile,True) # read mask defintion data from TPF file maskimg, pixcoord1, pixcoord2, status = kepio.readMaskDefinition( infile, logfile, True) npix = np.size(np.nonzero(maskimg)[0]) print('') print(' KepID: %s' % kepid) print(' BJD: %.2f' % (barytime[rownum - 1] + 2454833.0)) print(' RA (J2000): %s' % ra) print('Dec (J2000): %s' % dec) print(' KepMag: %s' % kepmag) print(' SkyGroup: %2s' % skygroup) print(' Season: %2s' % str(season)) print(' Channel: %2s' % channel) print(' Module: %2s' % module) print(' Output: %1s' % output) print('') # is this a good row with finite timestamp and pixels? if not np.isfinite(barytime[rownum - 1]) or np.nansum( fluxpixels[rownum - 1, :]) == np.nan: message = 'ERROR -- KEPFIELD: Row ' + str( rownum) + ' is a bad quality timestamp' status = kepmsg.err(logfile, message, True) # construct input pixel image flux = fluxpixels[rownum - 1, :] ferr = errpixels[rownum - 1, :] DATx = np.arange(column, column + xdim) DATy = np.arange(row, row + ydim) # image scale and intensity limits of pixel data n = 0 DATimg = np.empty((ydim, xdim)) ERRimg = np.empty((ydim, xdim)) for i in range(ydim): for j in range(xdim): DATimg[i, j] = flux[n] ERRimg[i, j] = ferr[n] n += 1 # determine suitable PRF calibration file if int(module) < 10: prefix = 'kplr0' else: prefix = 'kplr' prfglob = prfdir + '/' + prefix + str(module) + '.' + str( output) + '*' + '_prf.fits' try: prffile = glob.glob(prfglob)[0] except: message = 'ERROR -- KEPPRF: No PRF file found in ' + prfdir kepmsg.err(logfile, message, True) return None # read PRF images prfn = [0, 0, 0, 0, 0] crpix1p = np.zeros((5), dtype='float32') crpix2p = np.zeros((5), dtype='float32') crval1p = np.zeros((5), dtype='float32') crval2p = np.zeros((5), dtype='float32') cdelt1p = np.zeros((5), dtype='float32') cdelt2p = np.zeros((5), dtype='float32') for i in range(5): prfn[i], crpix1p[i], crpix2p[i], crval1p[i], crval2p[i], cdelt1p[i], cdelt2p[i], status \ = kepio.readPRFimage(prffile,i+1,logfile,True) prfn = np.array(prfn) PRFx = np.arange(0.5, np.shape(prfn[0])[1] + 0.5) PRFy = np.arange(0.5, np.shape(prfn[0])[0] + 0.5) PRFx = (PRFx - np.size(PRFx) / 2) * cdelt1p[0] PRFy = (PRFy - np.size(PRFy) / 2) * cdelt2p[0] # interpolate the calibrated PRF shape to the target position prf = np.zeros(np.shape(prfn[0]), dtype='float32') prfWeight = np.zeros((5), dtype='float32') for i in range(5): prfWeight[i] = np.sqrt((column - crval1p[i])**2 + (row - crval2p[i])**2) if prfWeight[i] == 0.0: prfWeight[i] = 1.0e-6 prf = prf + prfn[i] / prfWeight[i] prf = prf / np.nansum(prf) / cdelt1p[0] / cdelt2p[0] # location of the data image centered on the PRF image (in PRF pixel units) prfDimY = int(ydim / cdelt1p[0]) prfDimX = int(xdim / cdelt2p[0]) PRFy0 = (np.shape(prf)[0] - prfDimY) / 2 PRFx0 = (np.shape(prf)[1] - prfDimX) / 2 # interpolation function over the PRF splineInterpolation = scipy.interpolate.RectBivariateSpline( PRFx, PRFy, prf) # construct mesh for background model if background: bx = np.arange(1., float(xdim + 1)) by = np.arange(1., float(ydim + 1)) xx, yy = np.meshgrid(np.linspace(bx.min(), bx.max(), xdim), np.linspace(by.min(), by.max(), ydim)) # fit PRF model to pixel data start = time.time() if focus and background: args = (DATx, DATy, DATimg, ERRimg, nsrc, border, xx, yy, splineInterpolation, float(x[0]), float(y[0])) ans = fmin_powell(kepfunc.PRFwithFocusAndBackground, guess, args=args, xtol=xtol, ftol=ftol, disp=False) elif focus and not background: args = (DATx, DATy, DATimg, ERRimg, nsrc, splineInterpolation, float(x[0]), float(y[0])) ans = fmin_powell(kepfunc.PRFwithFocus, guess, args=args, xtol=xtol, ftol=ftol, disp=False) elif background and not focus: args = (DATx, DATy, DATimg, ERRimg, nsrc, border, xx, yy, splineInterpolation, float(x[0]), float(y[0])) ans = fmin_powell(kepfunc.PRFwithBackground, guess, args=args, xtol=xtol, ftol=ftol, disp=False) else: args = (DATx, DATy, DATimg, ERRimg, nsrc, splineInterpolation, float(x[0]), float(y[0])) ans = fmin_powell(kepfunc.PRF, guess, args=args, xtol=xtol, ftol=ftol, disp=False) kepmsg.log(logfile, 'Convergence time = %.2fs\n' % (time.time() - start), True) # pad the PRF data if the PRF array is smaller than the data array flux = [] OBJx = [] OBJy = [] PRFmod = np.zeros((prfDimY, prfDimX)) if PRFy0 < 0 or PRFx0 < 0.0: PRFmod = np.zeros((prfDimY, prfDimX)) superPRF = np.zeros((prfDimY + 1, prfDimX + 1)) superPRF[np.abs(PRFy0):np.abs(PRFy0) + np.shape(prf)[0], np.abs(PRFx0):np.abs(PRFx0) + np.shape(prf)[1]] = prf prf = superPRF * 1.0 PRFy0 = 0 PRFx0 = 0 # rotate the PRF model around its center if focus: angle = ans[-1] prf = rotate(prf, -angle, reshape=False, mode='nearest') # iterate through the sources in the best fit PSF model for i in range(nsrc): flux.append(ans[i]) OBJx.append(ans[nsrc + i]) OBJy.append(ans[nsrc * 2 + i]) # calculate best-fit model y = (OBJy[i] - np.mean(DATy)) / cdelt1p[0] x = (OBJx[i] - np.mean(DATx)) / cdelt2p[0] prfTmp = shift(prf, [y, x], order=3, mode='constant') prfTmp = prfTmp[PRFy0:PRFy0 + prfDimY, PRFx0:PRFx0 + prfDimX] PRFmod = PRFmod + prfTmp * flux[i] wx = 1.0 wy = 1.0 angle = 0 b = 0.0 # write out best fit parameters txt = 'Flux = %10.2f e-/s ' % flux[i] txt += 'X = %9.4f pix ' % OBJx[i] txt += 'Y = %9.4f pix ' % OBJy[i] kepmsg.log(logfile, txt, True) if background: bterms = border + 1 if bterms == 1: b = ans[nsrc * 3] else: bcoeff = np.array([ ans[nsrc * 3:nsrc * 3 + bterms], ans[nsrc * 3 + bterms:nsrc * 3 + bterms * 2] ]) bkg = kepfunc.polyval2d(xx, yy, bcoeff) b = nanmean(bkg.reshape(bkg.size)) txt = '\n Mean background = %.2f e-/s' % b kepmsg.log(logfile, txt, True) if focus: wx = ans[-3] wy = ans[-2] angle = ans[-1] if not background: kepmsg.log(logfile, '', True) kepmsg.log(logfile, ' X/Y focus factors = %.3f/%.3f' % (wx, wy), True) kepmsg.log(logfile, 'PRF rotation angle = %.2f deg' % angle, True) # measure flux fraction and contamination # LUGER: This looks horribly bugged. ``PRFall`` is certainly NOT the sum of the all the sources. # Check out my comments in ``kepfunc.py``. PRFall = kepfunc.PRF2DET(flux, OBJx, OBJy, DATx, DATy, wx, wy, angle, splineInterpolation) PRFone = kepfunc.PRF2DET([flux[0]], [OBJx[0]], [OBJy[0]], DATx, DATy, wx, wy, angle, splineInterpolation) # LUGER: Add up contaminant fluxes PRFcont = np.zeros_like(PRFone) for ncont in range(1, len(flux)): PRFcont += kepfunc.PRF2DET([flux[ncont]], [OBJx[ncont]], [OBJy[ncont]], DATx, DATy, wx, wy, angle, splineInterpolation) PRFcont[np.where(PRFcont < 0)] = 0 FluxInMaskAll = np.nansum(PRFall) FluxInMaskOne = np.nansum(PRFone) FluxInAperAll = 0.0 FluxInAperOne = 0.0 FluxInAperAllTrue = 0.0 for i in range(1, ydim): for j in range(1, xdim): if kepstat.bitInBitmap(maskimg[i, j], 2): FluxInAperAll += PRFall[i, j] FluxInAperOne += PRFone[i, j] FluxInAperAllTrue += PRFone[i, j] + PRFcont[i, j] FluxFraction = FluxInAperOne / flux[0] try: Contamination = (FluxInAperAll - FluxInAperOne) / FluxInAperAll except: Contamination = 0.0 # LUGER: Pixel crowding metrics Crowding = PRFone / (PRFone + PRFcont) Crowding[np.where(Crowding < 0)] = np.nan # LUGER: Optimal aperture crowding metric CrowdAper = FluxInAperOne / FluxInAperAllTrue kepmsg.log( logfile, '\n Total flux in mask = %.2f e-/s' % FluxInMaskAll, True) kepmsg.log( logfile, ' Target flux in mask = %.2f e-/s' % FluxInMaskOne, True) kepmsg.log( logfile, ' Total flux in aperture = %.2f e-/s' % FluxInAperAll, True) kepmsg.log( logfile, ' Target flux in aperture = %.2f e-/s' % FluxInAperOne, True) kepmsg.log( logfile, ' Target flux fraction in aperture = %.2f%%' % (FluxFraction * 100.0), True) kepmsg.log( logfile, 'Contamination fraction in aperture = %.2f%%' % (Contamination * 100.0), True) kepmsg.log(logfile, ' Crowding metric in aperture = %.4f' % (CrowdAper), True) kepmsg.log(logfile, ' Crowding metric from TPF = %.4f' % (CrowdTPF), True) # constuct model PRF in detector coordinates PRFfit = PRFall + 0.0 if background and bterms == 1: PRFfit = PRFall + b if background and bterms > 1: PRFfit = PRFall + bkg # calculate residual of DATA - FIT PRFres = DATimg - PRFfit FLUXres = np.nansum(PRFres) / npix # calculate the sum squared difference between data and model Pearson = np.abs(np.nansum(np.square(DATimg - PRFfit) / PRFfit)) Chi2 = np.nansum(np.square(DATimg - PRFfit) / np.square(ERRimg)) DegOfFreedom = npix - len(guess) - 1 try: kepmsg.log(logfile, '\n Residual flux = %.2f e-/s' % FLUXres, True) kepmsg.log( logfile, 'Pearson\'s chi^2 test = %d for %d dof' % (Pearson, DegOfFreedom), True) except: pass kepmsg.log(logfile, ' Chi^2 test = %d for %d dof' % (Chi2, DegOfFreedom), True) # image scale and intensity limits for plotting images imgdat_pl, zminfl, zmaxfl = kepplot.intScale2D(DATimg, imscale) imgprf_pl, zminpr, zmaxpr = kepplot.intScale2D(PRFmod, imscale) imgfit_pl, zminfi, zmaxfi = kepplot.intScale2D(PRFfit, imscale) imgres_pl, zminre, zmaxre = kepplot.intScale2D(PRFres, 'linear') if imscale == 'linear': zmaxpr *= 0.9 elif imscale == 'logarithmic': zmaxpr = np.max(zmaxpr) zminpr = zmaxpr / 2 # plot pl.figure(figsize=[12, 10]) pl.clf() # data plotimage(imgdat_pl, zminfl, zmaxfl, 1, row, column, xdim, ydim, 0.07, 0.58, 'observation', cmap, lcolor) pl.text(0.05, 0.05, 'CROWDSAP: %.4f' % CrowdTPF, horizontalalignment='left', verticalalignment='center', fontsize=18, fontweight=500, color=lcolor, transform=pl.gca().transAxes) kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 1, acolor, '--', 0.5) kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 2, acolor, '-', 3.0) # model plotimage(imgprf_pl, zminpr, zmaxpr, 2, row, column, xdim, ydim, 0.445, 0.58, 'model', cmap, lcolor) pl.text(0.05, 0.05, 'Crowding: %.4f' % CrowdAper, horizontalalignment='left', verticalalignment='center', fontsize=18, fontweight=500, color=lcolor, transform=pl.gca().transAxes) for x, y in zip(OBJx, OBJy): pl.scatter(x, y, marker='x', color='w') kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 1, acolor, '--', 0.5) kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 2, acolor, '-', 3.0) if srcinfo is not None: kepid, sx, sy, kepmag = srcinfo for i in range(len(sx) - 1, -1, -1): if kepid[i] != 0 and kepmag[i] != 0.0: size = max( np.array([ 80.0, 80.0 + (2.5**(18.0 - max(12.0, float(kepmag[i])))) * 250.0 ])) pl.scatter(sx[i], sy[i], s=size, facecolors='g', edgecolors='k', alpha=0.1) else: pl.scatter(sx[i], sy[i], s=80, facecolors='r', edgecolors='k', alpha=0.1) # binned model plotimage(imgfit_pl, zminfl, zmaxfl, 3, row, column, xdim, ydim, 0.07, 0.18, 'fit', cmap, lcolor, crowd=Crowding) kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 1, acolor, '--', 0.5) kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 2, acolor, '-', 3.0) # residuals reslim = max(np.abs(zminre), np.abs(zmaxre)) plotimage(imgres_pl, -reslim, reslim, 4, row, column, xdim, ydim, 0.445, 0.18, 'residual', 'coolwarm', lcolor) kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 1, acolor, '--', 0.5) kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 2, acolor, '-', 3.0) # plot data color bar barwin = pl.axes([0.84, 0.18, 0.03, 0.8]) if imscale == 'linear': brange = np.arange(zminfl, zmaxfl, (zmaxfl - zminfl) / 1000) elif imscale == 'logarithmic': brange = np.arange(10.0**zminfl, 10.0**zmaxfl, (10.0**zmaxfl - 10.0**zminfl) / 1000) elif imscale == 'squareroot': brange = np.arange(zminfl**2, zmaxfl**2, (zmaxfl**2 - zminfl**2) / 1000) if imscale == 'linear': barimg = np.resize(brange, (1000, 1)) elif imscale == 'logarithmic': barimg = np.log10(np.resize(brange, (1000, 1))) elif imscale == 'squareroot': barimg = np.sqrt(np.resize(brange, (1000, 1))) try: nrm = len(str(int(np.nanmax(brange)))) - 1 except: nrm = 0 brange = brange / 10**nrm pl.imshow(barimg, aspect='auto', interpolation='nearest', origin='lower', vmin=np.nanmin(barimg), vmax=np.nanmax(barimg), extent=(0.0, 1.0, brange[0], brange[-1]), cmap=cmap) barwin.yaxis.tick_right() barwin.yaxis.set_label_position('right') barwin.yaxis.set_major_locator(MaxNLocator(7)) pl.gca().yaxis.set_major_formatter(pl.ScalarFormatter(useOffset=False)) pl.gca().set_autoscale_on(False) pl.setp(pl.gca(), xticklabels=[], xticks=[]) pl.ylabel('Flux (10$^%d$ e$^-$ s$^{-1}$)' % nrm) pl.setp(barwin.get_yticklabels(), 'rotation', 90) barwin.yaxis.set_major_formatter(FormatStrFormatter('%.1f')) # plot residual color bar barwin = pl.axes([0.07, 0.08, 0.75, 0.03]) brange = np.arange(-reslim, reslim, reslim / 500) barimg = np.resize(brange, (1, 1000)) pl.imshow(barimg, aspect='auto', interpolation='nearest', origin='lower', vmin=np.nanmin(barimg), vmax=np.nanmax(barimg), extent=(brange[0], brange[-1], 0.0, 1.0), cmap='coolwarm') barwin.xaxis.set_major_locator(MaxNLocator(7)) pl.gca().xaxis.set_major_formatter(pl.ScalarFormatter(useOffset=False)) pl.gca().set_autoscale_on(False) pl.setp(pl.gca(), yticklabels=[], yticks=[]) pl.xlabel('Residuals (e$^-$ s$^{-1}$)') barwin.xaxis.set_major_formatter(FormatStrFormatter('%.1f')) # render plot pl.show(block=True) pl.close() # stop time kepmsg.clock('\nKEPPRF ended at', logfile, True) return Crowding
def kepprfphot(infile,outroot,columns,rows,fluxes,border,background,focus,prfdir,ranges, tolerance,ftolerance,qualflags,plt,clobber,verbose,logfile,status,cmdLine=False): # input arguments status = 0 seterr(all="ignore") # log the call hashline = '----------------------------------------------------------------------------' kepmsg.log(logfile,hashline,verbose) call = 'KEPPRFPHOT -- ' call += 'infile='+infile+' ' call += 'outroot='+outroot+' ' call += 'columns='+columns+' ' call += 'rows='+rows+' ' call += 'fluxes='+fluxes+' ' call += 'border='+str(border)+' ' bground = 'n' if (background): bground = 'y' call += 'background='+bground+' ' focs = 'n' if (focus): focs = 'y' call += 'focus='+focs+' ' call += 'prfdir='+prfdir+' ' call += 'ranges='+ranges+' ' call += 'xtol='+str(tolerance)+' ' call += 'ftol='+str(ftolerance)+' ' quality = 'n' if (qualflags): quality = 'y' call += 'qualflags='+quality+' ' plotit = 'n' if (plt): plotit = 'y' call += 'plot='+plotit+' ' overwrite = 'n' if (clobber): overwrite = 'y' call += 'clobber='+overwrite+ ' ' chatter = 'n' if (verbose): chatter = 'y' call += 'verbose='+chatter+' ' call += 'logfile='+logfile kepmsg.log(logfile,call+'\n',verbose) # test log file logfile = kepmsg.test(logfile) # start time kepmsg.clock('KEPPRFPHOT started at',logfile,verbose) # number of sources if status == 0: work = fluxes.strip() work = re.sub(' ',',',work) work = re.sub(';',',',work) nsrc = len(work.split(',')) # construct inital guess vector for fit if status == 0: guess = [] try: f = fluxes.strip().split(',') x = columns.strip().split(',') y = rows.strip().split(',') for i in range(len(f)): f[i] = float(f[i]) except: f = fluxes x = columns y = rows nsrc = len(f) for i in range(nsrc): try: guess.append(float(f[i])) except: message = 'ERROR -- KEPPRF: Fluxes must be floating point numbers' status = kepmsg.err(logfile,message,verbose) if status == 0: if len(x) != nsrc or len(y) != nsrc: message = 'ERROR -- KEPFIT:FITMULTIPRF: Guesses for rows, columns and ' message += 'fluxes must have the same number of sources' status = kepmsg.err(logfile,message,verbose) if status == 0: for i in range(nsrc): try: guess.append(float(x[i])) except: message = 'ERROR -- KEPPRF: Columns must be floating point numbers' status = kepmsg.err(logfile,message,verbose) if status == 0: for i in range(nsrc): try: guess.append(float(y[i])) except: message = 'ERROR -- KEPPRF: Rows must be floating point numbers' status = kepmsg.err(logfile,message,verbose) if status == 0 and background: if border == 0: guess.append(0.0) else: for i in range((border+1)*2): guess.append(0.0) if status == 0 and focus: guess.append(1.0); guess.append(1.0); guess.append(0.0) # clobber output file for i in range(nsrc): outfile = '%s_%d.fits' % (outroot, i) if clobber: status = kepio.clobber(outfile,logfile,verbose) if kepio.fileexists(outfile): message = 'ERROR -- KEPPRFPHOT: ' + outfile + ' exists. Use --clobber' status = kepmsg.err(logfile,message,verbose) # open TPF FITS file if status == 0: try: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, barytime, status = \ kepio.readTPF(infile,'TIME',logfile,verbose) except: message = 'ERROR -- KEPPRFPHOT: is %s a Target Pixel File? ' % infile status = kepmsg.err(logfile,message,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, tcorr, status = \ kepio.readTPF(infile,'TIMECORR',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, cadno, status = \ kepio.readTPF(infile,'CADENCENO',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, fluxpixels, status = \ kepio.readTPF(infile,'FLUX',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, errpixels, status = \ kepio.readTPF(infile,'FLUX_ERR',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, poscorr1, status = \ kepio.readTPF(infile,'POS_CORR1',logfile,verbose) if status != 0: poscorr1 = numpy.zeros((len(barytime)),dtype='float32') poscorr1[:] = numpy.nan status = 0 if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, poscorr2, status = \ kepio.readTPF(infile,'POS_CORR2',logfile,verbose) if status != 0: poscorr2 = numpy.zeros((len(barytime)),dtype='float32') poscorr2[:] = numpy.nan status = 0 if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, qual, status = \ kepio.readTPF(infile,'QUALITY',logfile,verbose) if status == 0: struct, status = kepio.openfits(infile,'readonly',logfile,verbose) if status == 0: tstart, tstop, bjdref, cadence, status = kepio.timekeys(struct,infile,logfile,verbose,status) # input file keywords and mask map if status == 0: cards0 = struct[0].header.cards cards1 = struct[1].header.cards cards2 = struct[2].header.cards maskmap = copy(struct[2].data) npix = numpy.size(numpy.nonzero(maskmap)[0]) # print target data if status == 0 and verbose: print('') print((' KepID: %s' % kepid)) print((' RA (J2000): %s' % ra)) print(('Dec (J2000): %s' % dec)) print((' KepMag: %s' % kepmag)) print((' SkyGroup: %2s' % skygroup)) print((' Season: %2s' % str(season))) print((' Channel: %2s' % channel)) print((' Module: %2s' % module)) print((' Output: %1s' % output)) print('') # determine suitable PRF calibration file if status == 0: if int(module) < 10: prefix = 'kplr0' else: prefix = 'kplr' prfglob = prfdir + '/' + prefix + str(module) + '.' + str(output) + '*' + '_prf.fits' try: prffile = glob.glob(prfglob)[0] except: message = 'ERROR -- KEPPRFPHOT: No PRF file found in ' + prfdir status = kepmsg.err(logfile,message,verbose) # read PRF images if status == 0: prfn = [0,0,0,0,0] crpix1p = numpy.zeros((5),dtype='float32') crpix2p = numpy.zeros((5),dtype='float32') crval1p = numpy.zeros((5),dtype='float32') crval2p = numpy.zeros((5),dtype='float32') cdelt1p = numpy.zeros((5),dtype='float32') cdelt2p = numpy.zeros((5),dtype='float32') for i in range(5): prfn[i], crpix1p[i], crpix2p[i], crval1p[i], crval2p[i], cdelt1p[i], cdelt2p[i], status \ = kepio.readPRFimage(prffile,i+1,logfile,verbose) PRFx = arange(0.5,shape(prfn[0])[1]+0.5) PRFy = arange(0.5,shape(prfn[0])[0]+0.5) PRFx = (PRFx - size(PRFx) / 2) * cdelt1p[0] PRFy = (PRFy - size(PRFy) / 2) * cdelt2p[0] # interpolate the calibrated PRF shape to the target position if status == 0: prf = zeros(shape(prfn[0]),dtype='float32') prfWeight = zeros((5),dtype='float32') for i in range(5): prfWeight[i] = sqrt((column - crval1p[i])**2 + (row - crval2p[i])**2) if prfWeight[i] == 0.0: prfWeight[i] = 1.0e6 prf = prf + prfn[i] / prfWeight[i] prf = prf / nansum(prf) prf = prf / cdelt1p[0] / cdelt2p[0] # location of the data image centered on the PRF image (in PRF pixel units) if status == 0: prfDimY = ydim / cdelt1p[0] prfDimX = xdim / cdelt2p[0] PRFy0 = (shape(prf)[0] - prfDimY) / 2 PRFx0 = (shape(prf)[1] - prfDimX) / 2 # construct input pixel image if status == 0: DATx = arange(column,column+xdim) DATy = arange(row,row+ydim) # interpolation function over the PRF if status == 0: splineInterpolation = scipy.interpolate.RectBivariateSpline(PRFx,PRFy,prf,kx=3,ky=3) # construct mesh for background model if status == 0: bx = numpy.arange(1.,float(xdim+1)) by = numpy.arange(1.,float(ydim+1)) xx, yy = numpy.meshgrid(numpy.linspace(bx.min(), bx.max(), xdim), numpy.linspace(by.min(), by.max(), ydim)) # Get time ranges for new photometry, flag good data if status == 0: barytime += bjdref tstart,tstop,status = kepio.timeranges(ranges,logfile,verbose) incl = numpy.zeros((len(barytime)),dtype='int') for rownum in range(len(barytime)): for winnum in range(len(tstart)): if barytime[rownum] >= tstart[winnum] and \ barytime[rownum] <= tstop[winnum] and \ (qual[rownum] == 0 or qualflags) and \ numpy.isfinite(barytime[rownum]) and \ numpy.isfinite(numpy.nansum(fluxpixels[rownum,:])): incl[rownum] = 1 if not numpy.in1d(1,incl): message = 'ERROR -- KEPPRFPHOT: No legal data within the range ' + ranges status = kepmsg.err(logfile,message,verbose) # filter out bad data if status == 0: n = 0 nincl = (incl == 1).sum() tim = zeros((nincl),'float64') tco = zeros((nincl),'float32') cad = zeros((nincl),'float32') flu = zeros((nincl,len(fluxpixels[0])),'float32') fer = zeros((nincl,len(fluxpixels[0])),'float32') pc1 = zeros((nincl),'float32') pc2 = zeros((nincl),'float32') qua = zeros((nincl),'float32') for rownum in range(len(barytime)): if incl[rownum] == 1: tim[n] = barytime[rownum] tco[n] = tcorr[rownum] cad[n] = cadno[rownum] flu[n,:] = fluxpixels[rownum] fer[n,:] = errpixels[rownum] pc1[n] = poscorr1[rownum] pc2[n] = poscorr2[rownum] qua[n] = qual[rownum] n += 1 barytime = tim * 1.0 tcorr = tco * 1.0 cadno = cad * 1.0 fluxpixels = flu * 1.0 errpixels = fer * 1.0 poscorr1 = pc1 * 1.0 poscorr2 = pc2 * 1.0 qual = qua * 1.0 # initialize plot arrays if status == 0: t = numpy.array([],dtype='float64') fl = []; dx = []; dy = []; bg = []; fx = []; fy = []; fa = []; rs = []; ch = [] for i in range(nsrc): fl.append(numpy.array([],dtype='float32')) dx.append(numpy.array([],dtype='float32')) dy.append(numpy.array([],dtype='float32')) # Preparing fit data message if status == 0: progress = numpy.arange(nincl) if verbose: txt = 'Preparing...' sys.stdout.write(txt) sys.stdout.flush() # single processor version if status == 0:# and not cmdLine: oldtime = 0.0 for rownum in range(numpy.min([80,len(barytime)])): try: if barytime[rownum] - oldtime > 0.5: ftol = 1.0e-10; xtol = 1.0e-10 except: pass args = (fluxpixels[rownum,:],errpixels[rownum,:],DATx,DATy,nsrc,border,xx,yy,PRFx,PRFy,splineInterpolation, guess,ftol,xtol,focus,background,rownum,80,float(x[i]),float(y[i]),False) guess = PRFfits(args) ftol = ftolerance; xtol = tolerance; oldtime = barytime[rownum] # Fit the time series: multi-processing if status == 0 and cmdLine: anslist = [] cad1 = 0; cad2 = 50 for i in range(int(nincl/50) + 1): try: fluxp = fluxpixels[cad1:cad2,:] errp = errpixels[cad1:cad2,:] progress = numpy.arange(cad1,cad2) except: fluxp = fluxpixels[cad1:nincl,:] errp = errpixels[cad1:nincl,:] progress = numpy.arange(cad1,nincl) try: args = zip(fluxp,errp,itertools.repeat(DATx),itertools.repeat(DATy), itertools.repeat(nsrc),itertools.repeat(border),itertools.repeat(xx), itertools.repeat(yy),itertools.repeat(PRFx),itertools.repeat(PRFy), itertools.repeat(splineInterpolation),itertools.repeat(guess), itertools.repeat(ftolerance),itertools.repeat(tolerance), itertools.repeat(focus),itertools.repeat(background),progress, itertools.repeat(numpy.arange(cad1,nincl)[-1]), itertools.repeat(float(x[0])), itertools.repeat(float(y[0])),itertools.repeat(True)) p = multiprocessing.Pool() model = [0.0] model = p.imap(PRFfits,args,chunksize=1) p.close() p.join() cad1 += 50; cad2 += 50 ans = array([array(item) for item in zip(*model)]) try: anslist = numpy.concatenate((anslist,ans.transpose()),axis=0) except: anslist = ans.transpose() guess = anslist[-1] ans = anslist.transpose() except: pass # single processor version if status == 0 and not cmdLine: oldtime = 0.0; ans = [] # for rownum in xrange(1,10): for rownum in range(nincl): proctime = time.time() try: if barytime[rownum] - oldtime > 0.5: ftol = 1.0e-10; xtol = 1.0e-10 except: pass args = (fluxpixels[rownum,:],errpixels[rownum,:],DATx,DATy,nsrc,border,xx,yy,PRFx,PRFy,splineInterpolation, guess,ftol,xtol,focus,background,rownum,nincl,float(x[0]),float(y[0]),True) guess = PRFfits(args) ans.append(guess) ftol = ftolerance; xtol = tolerance; oldtime = barytime[rownum] ans = array(ans).transpose() # unpack the best fit parameters if status == 0: flux = []; OBJx = []; OBJy = [] na = shape(ans)[1] for i in range(nsrc): flux.append(ans[i,:]) OBJx.append(ans[nsrc+i,:]) OBJy.append(ans[nsrc*2+i,:]) try: bterms = border + 1 if bterms == 1: b = ans[nsrc*3,:] else: b = array([]) bkg = [] for i in range(na): bcoeff = array([ans[nsrc*3:nsrc*3+bterms,i],ans[nsrc*3+bterms:nsrc*3+bterms*2,i]]) bkg.append(kepfunc.polyval2d(xx,yy,bcoeff)) b = numpy.append(b,nanmean(bkg[-1].reshape(bkg[-1].size))) except: b = zeros((na)) if focus: wx = ans[-3,:]; wy = ans[-2,:]; angle = ans[-1,:] else: wx = ones((na)); wy = ones((na)); angle = zeros((na)) # constuct model PRF in detector coordinates if status == 0: residual = []; chi2 = [] for i in range(na): f = empty((nsrc)) x = empty((nsrc)) y = empty((nsrc)) for j in range(nsrc): f[j] = flux[j][i] x[j] = OBJx[j][i] y[j] = OBJy[j][i] PRFfit = kepfunc.PRF2DET(f,x,y,DATx,DATy,wx[i],wy[i],angle[i],splineInterpolation) if background and bterms == 1: PRFfit = PRFfit + b[i] if background and bterms > 1: PRFfit = PRFfit + bkg[i] # calculate residual of DATA - FIT xdim = shape(xx)[1] ydim = shape(yy)[0] DATimg = numpy.empty((ydim,xdim)) n = 0 for k in range(ydim): for j in range(xdim): DATimg[k,j] = fluxpixels[i,n] n += 1 PRFres = DATimg - PRFfit residual.append(numpy.nansum(PRFres) / npix) # calculate the sum squared difference between data and model chi2.append(abs(numpy.nansum(numpy.square(DATimg - PRFfit) / PRFfit))) # load the output arrays if status == 0: otime = barytime - bjdref otimecorr = tcorr ocadenceno = cadno opos_corr1 = poscorr1 opos_corr2 = poscorr2 oquality = qual opsf_bkg = b opsf_focus1 = wx opsf_focus2 = wy opsf_rotation = angle opsf_residual = residual opsf_chi2 = chi2 opsf_flux_err = numpy.empty((na)); opsf_flux_err.fill(numpy.nan) opsf_centr1_err = numpy.empty((na)); opsf_centr1_err.fill(numpy.nan) opsf_centr2_err = numpy.empty((na)); opsf_centr2_err.fill(numpy.nan) opsf_bkg_err = numpy.empty((na)); opsf_bkg_err.fill(numpy.nan) opsf_flux = [] opsf_centr1 = [] opsf_centr2 = [] for i in range(nsrc): opsf_flux.append(flux[i]) opsf_centr1.append(OBJx[i]) opsf_centr2.append(OBJy[i]) # load the plot arrays if status == 0: t = barytime for i in range(nsrc): fl[i] = flux[i] dx[i] = OBJx[i] dy[i] = OBJy[i] bg = b fx = wx fy = wy fa = angle rs = residual ch = chi2 # construct output primary extension if status == 0: for j in range(nsrc): hdu0 = pyfits.PrimaryHDU() for i in range(len(cards0)): if cards0[i].key not in list(hdu0.header.keys()): hdu0.header.update(cards0[i].key, cards0[i].value, cards0[i].comment) else: hdu0.header.cards[cards0[i].key].comment = cards0[i].comment status = kepkey.history(call,hdu0,outfile,logfile,verbose) outstr = HDUList(hdu0) # construct output light curve extension col1 = Column(name='TIME',format='D',unit='BJD - 2454833',array=otime) col2 = Column(name='TIMECORR',format='E',unit='d',array=otimecorr) col3 = Column(name='CADENCENO',format='J',array=ocadenceno) col4 = Column(name='PSF_FLUX',format='E',unit='e-/s',array=opsf_flux[j]) col5 = Column(name='PSF_FLUX_ERR',format='E',unit='e-/s',array=opsf_flux_err) col6 = Column(name='PSF_BKG',format='E',unit='e-/s/pix',array=opsf_bkg) col7 = Column(name='PSF_BKG_ERR',format='E',unit='e-/s',array=opsf_bkg_err) col8 = Column(name='PSF_CENTR1',format='E',unit='pixel',array=opsf_centr1[j]) col9 = Column(name='PSF_CENTR1_ERR',format='E',unit='pixel',array=opsf_centr1_err) col10 = Column(name='PSF_CENTR2',format='E',unit='pixel',array=opsf_centr2[j]) col11 = Column(name='PSF_CENTR2_ERR',format='E',unit='pixel',array=opsf_centr2_err) col12 = Column(name='PSF_FOCUS1',format='E',array=opsf_focus1) col13 = Column(name='PSF_FOCUS2',format='E',array=opsf_focus2) col14 = Column(name='PSF_ROTATION',format='E',unit='deg',array=opsf_rotation) col15 = Column(name='PSF_RESIDUAL',format='E',unit='e-/s',array=opsf_residual) col16 = Column(name='PSF_CHI2',format='E',array=opsf_chi2) col17 = Column(name='POS_CORR1',format='E',unit='pixel',array=opos_corr1) col18 = Column(name='POS_CORR2',format='E',unit='pixel',array=opos_corr2) col19 = Column(name='SAP_QUALITY',format='J',array=oquality) cols = ColDefs([col1,col2,col3,col4,col5,col6,col7,col8,col9,col10,col11, col12,col13,col14,col15,col16,col17,col18,col19]) hdu1 = new_table(cols) for i in range(len(cards1)): if (cards1[i].key not in list(hdu1.header.keys()) and cards1[i].key[:4] not in ['TTYP','TFOR','TUNI','TDIS','TDIM','WCAX','1CTY', '2CTY','1CRP','2CRP','1CRV','2CRV','1CUN','2CUN', '1CDE','2CDE','1CTY','2CTY','1CDL','2CDL','11PC', '12PC','21PC','22PC']): hdu1.header.update(cards1[i].key, cards1[i].value, cards1[i].comment) outstr.append(hdu1) # construct output mask bitmap extension hdu2 = ImageHDU(maskmap) for i in range(len(cards2)): if cards2[i].key not in list(hdu2.header.keys()): hdu2.header.update(cards2[i].key, cards2[i].value, cards2[i].comment) else: hdu2.header.cards[cards2[i].key].comment = cards2[i].comment outstr.append(hdu2) # write output file outstr.writeto(outroot + '_' + str(j) + '.fits',checksum=True) # close input structure status = kepio.closefits(struct,logfile,verbose) # clean up x-axis unit if status == 0: barytime0 = float(int(t[0] / 100) * 100.0) t -= barytime0 t = numpy.insert(t,[0],[t[0]]) t = numpy.append(t,[t[-1]]) xlab = 'BJD $-$ %d' % barytime0 # plot the light curves if status == 0: bg = numpy.insert(bg,[0],[-1.0e10]) bg = numpy.append(bg,-1.0e10) fx = numpy.insert(fx,[0],[fx[0]]) fx = numpy.append(fx,fx[-1]) fy = numpy.insert(fy,[0],[fy[0]]) fy = numpy.append(fy,fy[-1]) fa = numpy.insert(fa,[0],[fa[0]]) fa = numpy.append(fa,fa[-1]) rs = numpy.insert(rs,[0],[-1.0e10]) rs = numpy.append(rs,-1.0e10) ch = numpy.insert(ch,[0],[-1.0e10]) ch = numpy.append(ch,-1.0e10) for i in range(nsrc): # clean up y-axis units nrm = math.ceil(math.log10(numpy.nanmax(fl[i]))) - 1.0 fl[i] /= 10**nrm if nrm == 0: ylab1 = 'e$^-$ s$^{-1}$' else: ylab1 = '10$^{%d}$ e$^-$ s$^{-1}$' % nrm xx = copy(dx[i]) yy = copy(dy[i]) ylab2 = 'offset (pixels)' # data limits xmin = numpy.nanmin(t) xmax = numpy.nanmax(t) ymin1 = numpy.nanmin(fl[i]) ymax1 = numpy.nanmax(fl[i]) ymin2 = numpy.nanmin(xx) ymax2 = numpy.nanmax(xx) ymin3 = numpy.nanmin(yy) ymax3 = numpy.nanmax(yy) ymin4 = numpy.nanmin(bg[1:-1]) ymax4 = numpy.nanmax(bg[1:-1]) ymin5 = numpy.nanmin([numpy.nanmin(fx),numpy.nanmin(fy)]) ymax5 = numpy.nanmax([numpy.nanmax(fx),numpy.nanmax(fy)]) ymin6 = numpy.nanmin(fa[1:-1]) ymax6 = numpy.nanmax(fa[1:-1]) ymin7 = numpy.nanmin(rs[1:-1]) ymax7 = numpy.nanmax(rs[1:-1]) ymin8 = numpy.nanmin(ch[1:-1]) ymax8 = numpy.nanmax(ch[1:-1]) xr = xmax - xmin yr1 = ymax1 - ymin1 yr2 = ymax2 - ymin2 yr3 = ymax3 - ymin3 yr4 = ymax4 - ymin4 yr5 = ymax5 - ymin5 yr6 = ymax6 - ymin6 yr7 = ymax7 - ymin7 yr8 = ymax8 - ymin8 fl[i] = numpy.insert(fl[i],[0],[0.0]) fl[i] = numpy.append(fl[i],0.0) # plot style try: params = {'backend': 'png', 'axes.linewidth': 2.5, 'axes.labelsize': 24, 'axes.font': 'sans-serif', 'axes.fontweight' : 'bold', 'text.fontsize': 12, 'legend.fontsize': 12, 'xtick.labelsize': 12, 'ytick.labelsize': 12} pylab.rcParams.update(params) except: pass # define size of plot on monitor screen pylab.figure(str(i+1) + ' ' + str(time.asctime(time.localtime())),figsize=[12,16]) # delete any fossil plots in the matplotlib window pylab.clf() # position first axes inside the plotting window ax = pylab.axes([0.11,0.523,0.78,0.45]) # force tick labels to be absolute rather than relative pylab.gca().xaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.gca().yaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) # no x-label pylab.setp(pylab.gca(),xticklabels=[]) # plot flux vs time ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') dt = 0 work1 = 2.0 * cadence / 86400 for j in range(1,len(t)-1): dt = t[j] - t[j-1] if dt < work1: ltime = numpy.append(ltime,t[j]) ldata = numpy.append(ldata,fl[i][j]) else: pylab.plot(ltime,ldata,color='#0000ff',linestyle='-',linewidth=1.0) ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') pylab.plot(ltime,ldata,color='#0000ff',linestyle='-',linewidth=1.0) # plot the fill color below data time series, with no data gaps pylab.fill(t,fl[i],fc='#ffff00',linewidth=0.0,alpha=0.2) # define plot x and y limits pylab.xlim(xmin - xr * 0.01, xmax + xr * 0.01) if ymin1 - yr1 * 0.01 <= 0.0: pylab.ylim(1.0e-10, ymax1 + yr1 * 0.01) else: pylab.ylim(ymin1 - yr1 * 0.01, ymax1 + yr1 * 0.01) # plot labels # pylab.xlabel(xlab, {'color' : 'k'}) try: pylab.ylabel('Source (' + ylab1 + ')', {'color' : 'k'}) except: ylab1 = '10**%d e-/s' % nrm pylab.ylabel('Source (' + ylab1 + ')', {'color' : 'k'}) # make grid on plot pylab.grid() # plot centroid tracks - position second axes inside the plotting window if focus and background: axs = [0.11,0.433,0.78,0.09] elif background or focus: axs = [0.11,0.388,0.78,0.135] else: axs = [0.11,0.253,0.78,0.27] ax1 = pylab.axes(axs) # force tick labels to be absolute rather than relative pylab.gca().xaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.gca().yaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.setp(pylab.gca(),xticklabels=[]) # plot dx vs time ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') dt = 0 work1 = 2.0 * cadence / 86400 for j in range(1,len(t)-1): dt = t[j] - t[j-1] if dt < work1: ltime = numpy.append(ltime,t[j]) ldata = numpy.append(ldata,xx[j-1]) else: ax1.plot(ltime,ldata,color='r',linestyle='-',linewidth=1.0) ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') ax1.plot(ltime,ldata,color='r',linestyle='-',linewidth=1.0) # define plot x and y limits pylab.xlim(xmin - xr * 0.01, xmax + xr * 0.01) pylab.ylim(ymin2 - yr2 * 0.03, ymax2 + yr2 * 0.03) # plot labels ax1.set_ylabel('X-' + ylab2, color='k', fontsize=11) # position second axes inside the plotting window ax2 = ax1.twinx() # force tick labels to be absolute rather than relative pylab.gca().xaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.gca().yaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.setp(pylab.gca(),xticklabels=[]) # plot dy vs time ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') dt = 0 work1 = 2.0 * cadence / 86400 for j in range(1,len(t)-1): dt = t[j] - t[j-1] if dt < work1: ltime = numpy.append(ltime,t[j]) ldata = numpy.append(ldata,yy[j-1]) else: ax2.plot(ltime,ldata,color='g',linestyle='-',linewidth=1.0) ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') ax2.plot(ltime,ldata,color='g',linestyle='-',linewidth=1.0) # define plot y limits pylab.xlim(xmin - xr * 0.01, xmax + xr * 0.01) pylab.ylim(ymin3 - yr3 * 0.03, ymax3 + yr3 * 0.03) # plot labels ax2.set_ylabel('Y-' + ylab2, color='k',fontsize=11) # background - position third axes inside the plotting window if background and focus: axs = [0.11,0.343,0.78,0.09] if background and not focus: axs = [0.11,0.253,0.78,0.135] if background: ax1 = pylab.axes(axs) # force tick labels to be absolute rather than relative pylab.gca().xaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.gca().yaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.setp(pylab.gca(),xticklabels=[]) # plot background vs time ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') dt = 0 work1 = 2.0 * cadence / 86400 for j in range(1,len(t)-1): dt = t[j] - t[j-1] if dt < work1: ltime = numpy.append(ltime,t[j]) ldata = numpy.append(ldata,bg[j]) else: ax1.plot(ltime,ldata,color='#0000ff',linestyle='-',linewidth=1.0) ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') ax1.plot(ltime,ldata,color='#0000ff',linestyle='-',linewidth=1.0) # plot the fill color below data time series, with no data gaps pylab.fill(t,bg,fc='#ffff00',linewidth=0.0,alpha=0.2) # define plot x and y limits pylab.xlim(xmin - xr * 0.01, xmax + xr * 0.01) pylab.ylim(ymin4 - yr4 * 0.03, ymax4 + yr4 * 0.03) # plot labels ax1.set_ylabel('Background \n(e$^-$ s$^{-1}$ pix$^{-1}$)', multialignment='center', color='k',fontsize=11) # make grid on plot pylab.grid() # position focus axes inside the plotting window if focus and background: axs = [0.11,0.253,0.78,0.09] if focus and not background: axs = [0.11,0.253,0.78,0.135] if focus: ax1 = pylab.axes(axs) # force tick labels to be absolute rather than relative pylab.gca().xaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.gca().yaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.setp(pylab.gca(),xticklabels=[]) # plot x-axis PSF width vs time ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') dt = 0 work1 = 2.0 * cadence / 86400 for j in range(1,len(t)-1): dt = t[j] - t[j-1] if dt < work1: ltime = numpy.append(ltime,t[j]) ldata = numpy.append(ldata,fx[j]) else: ax1.plot(ltime,ldata,color='r',linestyle='-',linewidth=1.0) ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') ax1.plot(ltime,ldata,color='r',linestyle='-',linewidth=1.0) # plot y-axis PSF width vs time ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') dt = 0 work1 = 2.0 * cadence / 86400 for j in range(1,len(t)-1): dt = t[j] - t[j-1] if dt < work1: ltime = numpy.append(ltime,t[j]) ldata = numpy.append(ldata,fy[j]) else: ax1.plot(ltime,ldata,color='g',linestyle='-',linewidth=1.0) ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') ax1.plot(ltime,ldata,color='g',linestyle='-',linewidth=1.0) # define plot x and y limits pylab.xlim(xmin - xr * 0.01, xmax + xr * 0.01) pylab.ylim(ymin5 - yr5 * 0.03, ymax5 + yr5 * 0.03) # plot labels ax1.set_ylabel('Pixel Scale\nFactor', multialignment='center', color='k',fontsize=11) # Focus rotation - position second axes inside the plotting window ax2 = ax1.twinx() # force tick labels to be absolute rather than relative pylab.gca().xaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.gca().yaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.setp(pylab.gca(),xticklabels=[]) # plot dy vs time ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') dt = 0 work1 = 2.0 * cadence / 86400 for j in range(1,len(t)-1): dt = t[j] - t[j-1] if dt < work1: ltime = numpy.append(ltime,t[j]) ldata = numpy.append(ldata,fa[j]) else: ax2.plot(ltime,ldata,color='#000080',linestyle='-',linewidth=1.0) ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') ax2.plot(ltime,ldata,color='#000080',linestyle='-',linewidth=1.0) # define plot y limits pylab.xlim(xmin - xr * 0.01, xmax + xr * 0.01) pylab.ylim(ymin6 - yr6 * 0.03, ymax6 + yr6 * 0.03) # plot labels ax2.set_ylabel('Rotation (deg)', color='k',fontsize=11) # fit residuals - position fifth axes inside the plotting window axs = [0.11,0.163,0.78,0.09] ax1 = pylab.axes(axs) # force tick labels to be absolute rather than relative pylab.gca().xaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.gca().yaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.setp(pylab.gca(),xticklabels=[]) # plot residual vs time ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') dt = 0 work1 = 2.0 * cadence / 86400 for j in range(1,len(t)-1): dt = t[j] - t[j-1] if dt < work1: ltime = numpy.append(ltime,t[j]) ldata = numpy.append(ldata,rs[j]) else: ax1.plot(ltime,ldata,color='b',linestyle='-',linewidth=1.0) ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') ax1.plot(ltime,ldata,color='b',linestyle='-',linewidth=1.0) # plot the fill color below data time series, with no data gaps pylab.fill(t,rs,fc='#ffff00',linewidth=0.0,alpha=0.2) # define plot x and y limits pylab.xlim(xmin - xr * 0.01, xmax + xr * 0.01) pylab.ylim(ymin7 - yr7 * 0.03, ymax7 + yr7 * 0.03) # plot labels ax1.set_ylabel('Residual \n(e$^-$ s$^{-1}$)', multialignment='center', color='k',fontsize=11) # make grid on plot pylab.grid() # fit chi square - position sixth axes inside the plotting window axs = [0.11,0.073,0.78,0.09] ax1 = pylab.axes(axs) # force tick labels to be absolute rather than relative pylab.gca().xaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.gca().yaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) # plot background vs time ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') dt = 0 work1 = 2.0 * cadence / 86400 for j in range(1,len(t)-1): dt = t[j] - t[j-1] if dt < work1: ltime = numpy.append(ltime,t[j]) ldata = numpy.append(ldata,ch[j]) else: ax1.plot(ltime,ldata,color='b',linestyle='-',linewidth=1.0) ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') ax1.plot(ltime,ldata,color='b',linestyle='-',linewidth=1.0) # plot the fill color below data time series, with no data gaps pylab.fill(t,ch,fc='#ffff00',linewidth=0.0,alpha=0.2) # define plot x and y limits pylab.xlim(xmin - xr * 0.01, xmax + xr * 0.01) pylab.ylim(ymin8 - yr8 * 0.03, ymax8 + yr8 * 0.03) # plot labels ax1.set_ylabel('$\chi^2$ (%d dof)' % (npix-len(guess)-1),color='k',fontsize=11) pylab.xlabel(xlab, {'color' : 'k'}) # make grid on plot pylab.grid() # render plot if status == 0: pylab.savefig(outroot + '_' + str(i) + '.png') if status == 0 and plt: if cmdLine: pylab.show(block=True) else: pylab.ion() pylab.plot([]) pylab.ioff() # stop time kepmsg.clock('\n\nKEPPRFPHOT ended at',logfile,verbose) return
def kepprf( infile, columns, rows, fluxes, rownum=0, border=0, background=0, focus=0, prfdir="../KeplerPRF", xtol=1.0e-6, ftol=1.0e-6, imscale="linear", cmap="YlOrBr", lcolor="k", acolor="b", logfile="kepcrowd.log", CrowdTPF=np.nan, srcinfo=None, **kwargs ): # log the call hashline = "----------------------------------------------------------------------------" kepmsg.log(logfile, hashline, True) call = "KEPPRF -- " call += "infile=" + infile + " " call += "rownum=" + str(rownum) + " " call += "columns=" + columns + " " call += "rows=" + rows + " " call += "fluxes=" + fluxes + " " call += "border=" + str(border) + " " bground = "n" if background: bground = "y" call += "background=" + bground + " " focs = "n" if focus: focs = "y" call += "focus=" + focs + " " call += "prfdir=" + prfdir + " " call += "xtol=" + str(xtol) + " " call += "ftol=" + str(xtol) + " " call += "logfile=" + logfile kepmsg.log(logfile, call + "\n", True) guess = [] try: f = fluxes.strip().split(",") x = columns.strip().split(",") y = rows.strip().split(",") for i in range(len(f)): f[i] = float(f[i]) except: f = fluxes x = columns y = rows nsrc = len(f) for i in range(nsrc): try: guess.append(float(f[i])) except: message = "ERROR -- KEPPRF: Fluxes must be floating point numbers" kepmsg.err(logfile, message, True) return None if len(x) != nsrc or len(y) != nsrc: message = "ERROR -- KEPFIT:FITMULTIPRF: Guesses for rows, columns and " message += "fluxes must have the same number of sources" kepmsg.err(logfile, message, True) return None for i in range(nsrc): try: guess.append(float(x[i])) except: message = "ERROR -- KEPPRF: Columns must be floating point numbers" kepmsg.err(logfile, message, True) return None for i in range(nsrc): try: guess.append(float(y[i])) except: message = "ERROR -- KEPPRF: Rows must be floating point numbers" kepmsg.err(logfile, message, True) return None if background: if border == 0: guess.append(0.0) else: for i in range((border + 1) * 2): guess.append(0.0) if focus: guess.append(1.0) guess.append(1.0) guess.append(0.0) # open TPF FITS file try: kepid, channel, skygroup, module, output, quarter, season, ra, dec, column, row, kepmag, xdim, ydim, barytime, status = kepio.readTPF( infile, "TIME", logfile, True ) except: message = "ERROR -- KEPPRF: is %s a Target Pixel File? " % infile kepmsg.err(logfile, message, True) return None kepid, channel, skygroup, module, output, quarter, season, ra, dec, column, row, kepmag, xdim, ydim, tcorr, status = kepio.readTPF( infile, "TIMECORR", logfile, True ) kepid, channel, skygroup, module, output, quarter, season, ra, dec, column, row, kepmag, xdim, ydim, cadno, status = kepio.readTPF( infile, "CADENCENO", logfile, True ) kepid, channel, skygroup, module, output, quarter, season, ra, dec, column, row, kepmag, xdim, ydim, fluxpixels, status = kepio.readTPF( infile, "FLUX", logfile, True ) kepid, channel, skygroup, module, output, quarter, season, ra, dec, column, row, kepmag, xdim, ydim, errpixels, status = kepio.readTPF( infile, "FLUX_ERR", logfile, True ) kepid, channel, skygroup, module, output, quarter, season, ra, dec, column, row, kepmag, xdim, ydim, qual, status = kepio.readTPF( infile, "QUALITY", logfile, True ) # read mask defintion data from TPF file maskimg, pixcoord1, pixcoord2, status = kepio.readMaskDefinition(infile, logfile, True) npix = np.size(np.nonzero(maskimg)[0]) print("") print(" KepID: %s" % kepid) print(" BJD: %.2f" % (barytime[rownum - 1] + 2454833.0)) print(" RA (J2000): %s" % ra) print("Dec (J2000): %s" % dec) print(" KepMag: %s" % kepmag) print(" SkyGroup: %2s" % skygroup) print(" Season: %2s" % str(season)) print(" Channel: %2s" % channel) print(" Module: %2s" % module) print(" Output: %1s" % output) print("") # is this a good row with finite timestamp and pixels? if not np.isfinite(barytime[rownum - 1]) or np.nansum(fluxpixels[rownum - 1, :]) == np.nan: message = "ERROR -- KEPFIELD: Row " + str(rownum) + " is a bad quality timestamp" status = kepmsg.err(logfile, message, True) # construct input pixel image flux = fluxpixels[rownum - 1, :] ferr = errpixels[rownum - 1, :] DATx = np.arange(column, column + xdim) DATy = np.arange(row, row + ydim) # image scale and intensity limits of pixel data n = 0 DATimg = np.empty((ydim, xdim)) ERRimg = np.empty((ydim, xdim)) for i in range(ydim): for j in range(xdim): DATimg[i, j] = flux[n] ERRimg[i, j] = ferr[n] n += 1 # determine suitable PRF calibration file if int(module) < 10: prefix = "kplr0" else: prefix = "kplr" prfglob = prfdir + "/" + prefix + str(module) + "." + str(output) + "*" + "_prf.fits" try: prffile = glob.glob(prfglob)[0] except: message = "ERROR -- KEPPRF: No PRF file found in " + prfdir kepmsg.err(logfile, message, True) return None # read PRF images prfn = [0, 0, 0, 0, 0] crpix1p = np.zeros((5), dtype="float32") crpix2p = np.zeros((5), dtype="float32") crval1p = np.zeros((5), dtype="float32") crval2p = np.zeros((5), dtype="float32") cdelt1p = np.zeros((5), dtype="float32") cdelt2p = np.zeros((5), dtype="float32") for i in range(5): prfn[i], crpix1p[i], crpix2p[i], crval1p[i], crval2p[i], cdelt1p[i], cdelt2p[i], status = kepio.readPRFimage( prffile, i + 1, logfile, True ) prfn = np.array(prfn) PRFx = np.arange(0.5, np.shape(prfn[0])[1] + 0.5) PRFy = np.arange(0.5, np.shape(prfn[0])[0] + 0.5) PRFx = (PRFx - np.size(PRFx) / 2) * cdelt1p[0] PRFy = (PRFy - np.size(PRFy) / 2) * cdelt2p[0] # interpolate the calibrated PRF shape to the target position prf = np.zeros(np.shape(prfn[0]), dtype="float32") prfWeight = np.zeros((5), dtype="float32") for i in range(5): prfWeight[i] = np.sqrt((column - crval1p[i]) ** 2 + (row - crval2p[i]) ** 2) if prfWeight[i] == 0.0: prfWeight[i] = 1.0e-6 prf = prf + prfn[i] / prfWeight[i] prf = prf / np.nansum(prf) / cdelt1p[0] / cdelt2p[0] # location of the data image centered on the PRF image (in PRF pixel units) prfDimY = int(ydim / cdelt1p[0]) prfDimX = int(xdim / cdelt2p[0]) PRFy0 = (np.shape(prf)[0] - prfDimY) / 2 PRFx0 = (np.shape(prf)[1] - prfDimX) / 2 # interpolation function over the PRF splineInterpolation = scipy.interpolate.RectBivariateSpline(PRFx, PRFy, prf) # construct mesh for background model if background: bx = np.arange(1.0, float(xdim + 1)) by = np.arange(1.0, float(ydim + 1)) xx, yy = np.meshgrid(np.linspace(bx.min(), bx.max(), xdim), np.linspace(by.min(), by.max(), ydim)) # fit PRF model to pixel data start = time.time() if focus and background: args = (DATx, DATy, DATimg, ERRimg, nsrc, border, xx, yy, splineInterpolation, float(x[0]), float(y[0])) ans = fmin_powell(kepfunc.PRFwithFocusAndBackground, guess, args=args, xtol=xtol, ftol=ftol, disp=False) elif focus and not background: args = (DATx, DATy, DATimg, ERRimg, nsrc, splineInterpolation, float(x[0]), float(y[0])) ans = fmin_powell(kepfunc.PRFwithFocus, guess, args=args, xtol=xtol, ftol=ftol, disp=False) elif background and not focus: args = (DATx, DATy, DATimg, ERRimg, nsrc, border, xx, yy, splineInterpolation, float(x[0]), float(y[0])) ans = fmin_powell(kepfunc.PRFwithBackground, guess, args=args, xtol=xtol, ftol=ftol, disp=False) else: args = (DATx, DATy, DATimg, ERRimg, nsrc, splineInterpolation, float(x[0]), float(y[0])) ans = fmin_powell(kepfunc.PRF, guess, args=args, xtol=xtol, ftol=ftol, disp=False) kepmsg.log(logfile, "Convergence time = %.2fs\n" % (time.time() - start), True) # pad the PRF data if the PRF array is smaller than the data array flux = [] OBJx = [] OBJy = [] PRFmod = np.zeros((prfDimY, prfDimX)) if PRFy0 < 0 or PRFx0 < 0.0: PRFmod = np.zeros((prfDimY, prfDimX)) superPRF = np.zeros((prfDimY + 1, prfDimX + 1)) superPRF[ np.abs(PRFy0) : np.abs(PRFy0) + np.shape(prf)[0], np.abs(PRFx0) : np.abs(PRFx0) + np.shape(prf)[1] ] = prf prf = superPRF * 1.0 PRFy0 = 0 PRFx0 = 0 # rotate the PRF model around its center if focus: angle = ans[-1] prf = rotate(prf, -angle, reshape=False, mode="nearest") # iterate through the sources in the best fit PSF model for i in range(nsrc): flux.append(ans[i]) OBJx.append(ans[nsrc + i]) OBJy.append(ans[nsrc * 2 + i]) # calculate best-fit model y = (OBJy[i] - np.mean(DATy)) / cdelt1p[0] x = (OBJx[i] - np.mean(DATx)) / cdelt2p[0] prfTmp = shift(prf, [y, x], order=3, mode="constant") prfTmp = prfTmp[PRFy0 : PRFy0 + prfDimY, PRFx0 : PRFx0 + prfDimX] PRFmod = PRFmod + prfTmp * flux[i] wx = 1.0 wy = 1.0 angle = 0 b = 0.0 # write out best fit parameters txt = "Flux = %10.2f e-/s " % flux[i] txt += "X = %9.4f pix " % OBJx[i] txt += "Y = %9.4f pix " % OBJy[i] kepmsg.log(logfile, txt, True) if background: bterms = border + 1 if bterms == 1: b = ans[nsrc * 3] else: bcoeff = np.array([ans[nsrc * 3 : nsrc * 3 + bterms], ans[nsrc * 3 + bterms : nsrc * 3 + bterms * 2]]) bkg = kepfunc.polyval2d(xx, yy, bcoeff) b = nanmean(bkg.reshape(bkg.size)) txt = "\n Mean background = %.2f e-/s" % b kepmsg.log(logfile, txt, True) if focus: wx = ans[-3] wy = ans[-2] angle = ans[-1] if not background: kepmsg.log(logfile, "", True) kepmsg.log(logfile, " X/Y focus factors = %.3f/%.3f" % (wx, wy), True) kepmsg.log(logfile, "PRF rotation angle = %.2f deg" % angle, True) # measure flux fraction and contamination # LUGER: This looks horribly bugged. ``PRFall`` is certainly NOT the sum of the all the sources. # Check out my comments in ``kepfunc.py``. PRFall = kepfunc.PRF2DET(flux, OBJx, OBJy, DATx, DATy, wx, wy, angle, splineInterpolation) PRFone = kepfunc.PRF2DET([flux[0]], [OBJx[0]], [OBJy[0]], DATx, DATy, wx, wy, angle, splineInterpolation) # LUGER: Add up contaminant fluxes PRFcont = np.zeros_like(PRFone) for ncont in range(1, len(flux)): PRFcont += kepfunc.PRF2DET( [flux[ncont]], [OBJx[ncont]], [OBJy[ncont]], DATx, DATy, wx, wy, angle, splineInterpolation ) PRFcont[np.where(PRFcont < 0)] = 0 FluxInMaskAll = np.nansum(PRFall) FluxInMaskOne = np.nansum(PRFone) FluxInAperAll = 0.0 FluxInAperOne = 0.0 FluxInAperAllTrue = 0.0 for i in range(1, ydim): for j in range(1, xdim): if kepstat.bitInBitmap(maskimg[i, j], 2): FluxInAperAll += PRFall[i, j] FluxInAperOne += PRFone[i, j] FluxInAperAllTrue += PRFone[i, j] + PRFcont[i, j] FluxFraction = FluxInAperOne / flux[0] try: Contamination = (FluxInAperAll - FluxInAperOne) / FluxInAperAll except: Contamination = 0.0 # LUGER: Pixel crowding metrics Crowding = PRFone / (PRFone + PRFcont) Crowding[np.where(Crowding < 0)] = np.nan # LUGER: Optimal aperture crowding metric CrowdAper = FluxInAperOne / FluxInAperAllTrue kepmsg.log(logfile, "\n Total flux in mask = %.2f e-/s" % FluxInMaskAll, True) kepmsg.log(logfile, " Target flux in mask = %.2f e-/s" % FluxInMaskOne, True) kepmsg.log(logfile, " Total flux in aperture = %.2f e-/s" % FluxInAperAll, True) kepmsg.log(logfile, " Target flux in aperture = %.2f e-/s" % FluxInAperOne, True) kepmsg.log(logfile, " Target flux fraction in aperture = %.2f%%" % (FluxFraction * 100.0), True) kepmsg.log(logfile, "Contamination fraction in aperture = %.2f%%" % (Contamination * 100.0), True) kepmsg.log(logfile, " Crowding metric in aperture = %.4f" % (CrowdAper), True) kepmsg.log(logfile, " Crowding metric from TPF = %.4f" % (CrowdTPF), True) # constuct model PRF in detector coordinates PRFfit = PRFall + 0.0 if background and bterms == 1: PRFfit = PRFall + b if background and bterms > 1: PRFfit = PRFall + bkg # calculate residual of DATA - FIT PRFres = DATimg - PRFfit FLUXres = np.nansum(PRFres) / npix # calculate the sum squared difference between data and model Pearson = np.abs(np.nansum(np.square(DATimg - PRFfit) / PRFfit)) Chi2 = np.nansum(np.square(DATimg - PRFfit) / np.square(ERRimg)) DegOfFreedom = npix - len(guess) - 1 try: kepmsg.log(logfile, "\n Residual flux = %.2f e-/s" % FLUXres, True) kepmsg.log(logfile, "Pearson's chi^2 test = %d for %d dof" % (Pearson, DegOfFreedom), True) except: pass kepmsg.log(logfile, " Chi^2 test = %d for %d dof" % (Chi2, DegOfFreedom), True) # image scale and intensity limits for plotting images imgdat_pl, zminfl, zmaxfl = kepplot.intScale2D(DATimg, imscale) imgprf_pl, zminpr, zmaxpr = kepplot.intScale2D(PRFmod, imscale) imgfit_pl, zminfi, zmaxfi = kepplot.intScale2D(PRFfit, imscale) imgres_pl, zminre, zmaxre = kepplot.intScale2D(PRFres, "linear") if imscale == "linear": zmaxpr *= 0.9 elif imscale == "logarithmic": zmaxpr = np.max(zmaxpr) zminpr = zmaxpr / 2 # plot pl.figure(figsize=[12, 10]) pl.clf() # data plotimage(imgdat_pl, zminfl, zmaxfl, 1, row, column, xdim, ydim, 0.07, 0.58, "observation", cmap, lcolor) pl.text( 0.05, 0.05, "CROWDSAP: %.4f" % CrowdTPF, horizontalalignment="left", verticalalignment="center", fontsize=18, fontweight=500, color=lcolor, transform=pl.gca().transAxes, ) kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 1, acolor, "--", 0.5) kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 2, acolor, "-", 3.0) # model plotimage(imgprf_pl, zminpr, zmaxpr, 2, row, column, xdim, ydim, 0.445, 0.58, "model", cmap, lcolor) pl.text( 0.05, 0.05, "Crowding: %.4f" % CrowdAper, horizontalalignment="left", verticalalignment="center", fontsize=18, fontweight=500, color=lcolor, transform=pl.gca().transAxes, ) for x, y in zip(OBJx, OBJy): pl.scatter(x, y, marker="x", color="w") kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 1, acolor, "--", 0.5) kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 2, acolor, "-", 3.0) if srcinfo is not None: kepid, sx, sy, kepmag = srcinfo for i in range(len(sx) - 1, -1, -1): if kepid[i] != 0 and kepmag[i] != 0.0: size = max(np.array([80.0, 80.0 + (2.5 ** (18.0 - max(12.0, float(kepmag[i])))) * 250.0])) pl.scatter(sx[i], sy[i], s=size, facecolors="g", edgecolors="k", alpha=0.1) else: pl.scatter(sx[i], sy[i], s=80, facecolors="r", edgecolors="k", alpha=0.1) # binned model plotimage(imgfit_pl, zminfl, zmaxfl, 3, row, column, xdim, ydim, 0.07, 0.18, "fit", cmap, lcolor, crowd=Crowding) kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 1, acolor, "--", 0.5) kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 2, acolor, "-", 3.0) # residuals reslim = max(np.abs(zminre), np.abs(zmaxre)) plotimage(imgres_pl, -reslim, reslim, 4, row, column, xdim, ydim, 0.445, 0.18, "residual", "coolwarm", lcolor) kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 1, acolor, "--", 0.5) kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 2, acolor, "-", 3.0) # plot data color bar barwin = pl.axes([0.84, 0.18, 0.03, 0.8]) if imscale == "linear": brange = np.arange(zminfl, zmaxfl, (zmaxfl - zminfl) / 1000) elif imscale == "logarithmic": brange = np.arange(10.0 ** zminfl, 10.0 ** zmaxfl, (10.0 ** zmaxfl - 10.0 ** zminfl) / 1000) elif imscale == "squareroot": brange = np.arange(zminfl ** 2, zmaxfl ** 2, (zmaxfl ** 2 - zminfl ** 2) / 1000) if imscale == "linear": barimg = np.resize(brange, (1000, 1)) elif imscale == "logarithmic": barimg = np.log10(np.resize(brange, (1000, 1))) elif imscale == "squareroot": barimg = np.sqrt(np.resize(brange, (1000, 1))) try: nrm = len(str(int(np.nanmax(brange)))) - 1 except: nrm = 0 brange = brange / 10 ** nrm pl.imshow( barimg, aspect="auto", interpolation="nearest", origin="lower", vmin=np.nanmin(barimg), vmax=np.nanmax(barimg), extent=(0.0, 1.0, brange[0], brange[-1]), cmap=cmap, ) barwin.yaxis.tick_right() barwin.yaxis.set_label_position("right") barwin.yaxis.set_major_locator(MaxNLocator(7)) pl.gca().yaxis.set_major_formatter(pl.ScalarFormatter(useOffset=False)) pl.gca().set_autoscale_on(False) pl.setp(pl.gca(), xticklabels=[], xticks=[]) pl.ylabel("Flux (10$^%d$ e$^-$ s$^{-1}$)" % nrm) pl.setp(barwin.get_yticklabels(), "rotation", 90) barwin.yaxis.set_major_formatter(FormatStrFormatter("%.1f")) # plot residual color bar barwin = pl.axes([0.07, 0.08, 0.75, 0.03]) brange = np.arange(-reslim, reslim, reslim / 500) barimg = np.resize(brange, (1, 1000)) pl.imshow( barimg, aspect="auto", interpolation="nearest", origin="lower", vmin=np.nanmin(barimg), vmax=np.nanmax(barimg), extent=(brange[0], brange[-1], 0.0, 1.0), cmap="coolwarm", ) barwin.xaxis.set_major_locator(MaxNLocator(7)) pl.gca().xaxis.set_major_formatter(pl.ScalarFormatter(useOffset=False)) pl.gca().set_autoscale_on(False) pl.setp(pl.gca(), yticklabels=[], yticks=[]) pl.xlabel("Residuals (e$^-$ s$^{-1}$)") barwin.xaxis.set_major_formatter(FormatStrFormatter("%.1f")) # render plot pl.show(block=True) pl.close() # stop time kepmsg.clock("\nKEPPRF ended at", logfile, True) return Crowding