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, 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 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 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, 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 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