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 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 kepprfphot(infile,outroot,columns,rows,fluxes,border,background,focus,prfdir,ranges, tolerance,ftolerance,qualflags,plt,clobber,verbose,logfile,status,cmdLine=False): # input arguments status = 0 seterr(all="ignore") # log the call hashline = '----------------------------------------------------------------------------' kepmsg.log(logfile,hashline,verbose) call = 'KEPPRFPHOT -- ' call += 'infile='+infile+' ' call += 'outroot='+outroot+' ' call += 'columns='+columns+' ' call += 'rows='+rows+' ' call += 'fluxes='+fluxes+' ' call += 'border='+str(border)+' ' bground = 'n' if (background): bground = 'y' call += 'background='+bground+' ' focs = 'n' if (focus): focs = 'y' call += 'focus='+focs+' ' call += 'prfdir='+prfdir+' ' call += 'ranges='+ranges+' ' call += 'xtol='+str(tolerance)+' ' call += 'ftol='+str(ftolerance)+' ' quality = 'n' if (qualflags): quality = 'y' call += 'qualflags='+quality+' ' plotit = 'n' if (plt): plotit = 'y' call += 'plot='+plotit+' ' overwrite = 'n' if (clobber): overwrite = 'y' call += 'clobber='+overwrite+ ' ' chatter = 'n' if (verbose): chatter = 'y' call += 'verbose='+chatter+' ' call += 'logfile='+logfile kepmsg.log(logfile,call+'\n',verbose) # test log file logfile = kepmsg.test(logfile) # start time kepmsg.clock('KEPPRFPHOT started at',logfile,verbose) # number of sources if status == 0: work = fluxes.strip() work = re.sub(' ',',',work) work = re.sub(';',',',work) nsrc = len(work.split(',')) # construct inital guess vector for fit if status == 0: guess = [] try: f = fluxes.strip().split(',') x = columns.strip().split(',') y = rows.strip().split(',') for i in xrange(len(f)): f[i] = float(f[i]) except: f = fluxes x = columns y = rows nsrc = len(f) for i in xrange(nsrc): try: guess.append(float(f[i])) except: message = 'ERROR -- KEPPRF: Fluxes must be floating point numbers' status = kepmsg.err(logfile,message,verbose) if status == 0: if len(x) != nsrc or len(y) != nsrc: message = 'ERROR -- KEPFIT:FITMULTIPRF: Guesses for rows, columns and ' message += 'fluxes must have the same number of sources' status = kepmsg.err(logfile,message,verbose) if status == 0: for i in xrange(nsrc): try: guess.append(float(x[i])) except: message = 'ERROR -- KEPPRF: Columns must be floating point numbers' status = kepmsg.err(logfile,message,verbose) if status == 0: for i in xrange(nsrc): try: guess.append(float(y[i])) except: message = 'ERROR -- KEPPRF: Rows must be floating point numbers' status = kepmsg.err(logfile,message,verbose) if status == 0 and background: if border == 0: guess.append(0.0) else: for i in range((border+1)*2): guess.append(0.0) if status == 0 and focus: guess.append(1.0); guess.append(1.0); guess.append(0.0) # clobber output file for i in range(nsrc): outfile = '%s_%d.fits' % (outroot, i) if clobber: status = kepio.clobber(outfile,logfile,verbose) if kepio.fileexists(outfile): message = 'ERROR -- KEPPRFPHOT: ' + outfile + ' exists. Use --clobber' status = kepmsg.err(logfile,message,verbose) # open TPF FITS file if status == 0: try: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, barytime, status = \ kepio.readTPF(infile,'TIME',logfile,verbose) except: message = 'ERROR -- KEPPRFPHOT: is %s a Target Pixel File? ' % infile status = kepmsg.err(logfile,message,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, tcorr, status = \ kepio.readTPF(infile,'TIMECORR',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, cadno, status = \ kepio.readTPF(infile,'CADENCENO',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, fluxpixels, status = \ kepio.readTPF(infile,'FLUX',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, errpixels, status = \ kepio.readTPF(infile,'FLUX_ERR',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, poscorr1, status = \ kepio.readTPF(infile,'POS_CORR1',logfile,verbose) if status != 0: poscorr1 = numpy.zeros((len(barytime)),dtype='float32') poscorr1[:] = numpy.nan status = 0 if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, poscorr2, status = \ kepio.readTPF(infile,'POS_CORR2',logfile,verbose) if status != 0: poscorr2 = numpy.zeros((len(barytime)),dtype='float32') poscorr2[:] = numpy.nan status = 0 if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, qual, status = \ kepio.readTPF(infile,'QUALITY',logfile,verbose) if status == 0: struct, status = kepio.openfits(infile,'readonly',logfile,verbose) if status == 0: tstart, tstop, bjdref, cadence, status = kepio.timekeys(struct,infile,logfile,verbose,status) # input file keywords and mask map if status == 0: cards0 = struct[0].header.cards cards1 = struct[1].header.cards cards2 = struct[2].header.cards maskmap = copy(struct[2].data) npix = numpy.size(numpy.nonzero(maskmap)[0]) # print target data if status == 0 and verbose: print '' print ' KepID: %s' % kepid print ' RA (J2000): %s' % ra print 'Dec (J2000): %s' % dec print ' KepMag: %s' % kepmag print ' SkyGroup: %2s' % skygroup print ' Season: %2s' % str(season) print ' Channel: %2s' % channel print ' Module: %2s' % module print ' Output: %1s' % output print '' # determine suitable PRF calibration file if status == 0: if int(module) < 10: prefix = 'kplr0' else: prefix = 'kplr' prfglob = prfdir + '/' + prefix + str(module) + '.' + str(output) + '*' + '_prf.fits' try: prffile = glob.glob(prfglob)[0] except: message = 'ERROR -- KEPPRFPHOT: No PRF file found in ' + prfdir status = kepmsg.err(logfile,message,verbose) # read PRF images if status == 0: prfn = [0,0,0,0,0] crpix1p = numpy.zeros((5),dtype='float32') crpix2p = numpy.zeros((5),dtype='float32') crval1p = numpy.zeros((5),dtype='float32') crval2p = numpy.zeros((5),dtype='float32') cdelt1p = numpy.zeros((5),dtype='float32') cdelt2p = numpy.zeros((5),dtype='float32') for i in range(5): prfn[i], crpix1p[i], crpix2p[i], crval1p[i], crval2p[i], cdelt1p[i], cdelt2p[i], status \ = kepio.readPRFimage(prffile,i+1,logfile,verbose) PRFx = arange(0.5,shape(prfn[0])[1]+0.5) PRFy = arange(0.5,shape(prfn[0])[0]+0.5) PRFx = (PRFx - size(PRFx) / 2) * cdelt1p[0] PRFy = (PRFy - size(PRFy) / 2) * cdelt2p[0] # interpolate the calibrated PRF shape to the target position if status == 0: prf = zeros(shape(prfn[0]),dtype='float32') prfWeight = zeros((5),dtype='float32') for i in xrange(5): prfWeight[i] = sqrt((column - crval1p[i])**2 + (row - crval2p[i])**2) if prfWeight[i] == 0.0: prfWeight[i] = 1.0e6 prf = prf + prfn[i] / prfWeight[i] prf = prf / nansum(prf) prf = prf / cdelt1p[0] / cdelt2p[0] # location of the data image centered on the PRF image (in PRF pixel units) if status == 0: prfDimY = ydim / cdelt1p[0] prfDimX = xdim / cdelt2p[0] PRFy0 = (shape(prf)[0] - prfDimY) / 2 PRFx0 = (shape(prf)[1] - prfDimX) / 2 # construct input pixel image if status == 0: DATx = arange(column,column+xdim) DATy = arange(row,row+ydim) # interpolation function over the PRF if status == 0: splineInterpolation = scipy.interpolate.RectBivariateSpline(PRFx,PRFy,prf,kx=3,ky=3) # construct mesh for background model if status == 0: bx = numpy.arange(1.,float(xdim+1)) by = numpy.arange(1.,float(ydim+1)) xx, yy = numpy.meshgrid(numpy.linspace(bx.min(), bx.max(), xdim), numpy.linspace(by.min(), by.max(), ydim)) # Get time ranges for new photometry, flag good data if status == 0: barytime += bjdref tstart,tstop,status = kepio.timeranges(ranges,logfile,verbose) incl = numpy.zeros((len(barytime)),dtype='int') for rownum in xrange(len(barytime)): for winnum in xrange(len(tstart)): if barytime[rownum] >= tstart[winnum] and \ barytime[rownum] <= tstop[winnum] and \ (qual[rownum] == 0 or qualflags) and \ numpy.isfinite(barytime[rownum]) and \ numpy.isfinite(numpy.nansum(fluxpixels[rownum,:])): incl[rownum] = 1 if not numpy.in1d(1,incl): message = 'ERROR -- KEPPRFPHOT: No legal data within the range ' + ranges status = kepmsg.err(logfile,message,verbose) # filter out bad data if status == 0: n = 0 nincl = (incl == 1).sum() tim = zeros((nincl),'float64') tco = zeros((nincl),'float32') cad = zeros((nincl),'float32') flu = zeros((nincl,len(fluxpixels[0])),'float32') fer = zeros((nincl,len(fluxpixels[0])),'float32') pc1 = zeros((nincl),'float32') pc2 = zeros((nincl),'float32') qua = zeros((nincl),'float32') for rownum in xrange(len(barytime)): if incl[rownum] == 1: tim[n] = barytime[rownum] tco[n] = tcorr[rownum] cad[n] = cadno[rownum] flu[n,:] = fluxpixels[rownum] fer[n,:] = errpixels[rownum] pc1[n] = poscorr1[rownum] pc2[n] = poscorr2[rownum] qua[n] = qual[rownum] n += 1 barytime = tim * 1.0 tcorr = tco * 1.0 cadno = cad * 1.0 fluxpixels = flu * 1.0 errpixels = fer * 1.0 poscorr1 = pc1 * 1.0 poscorr2 = pc2 * 1.0 qual = qua * 1.0 # initialize plot arrays if status == 0: t = numpy.array([],dtype='float64') fl = []; dx = []; dy = []; bg = []; fx = []; fy = []; fa = []; rs = []; ch = [] for i in range(nsrc): fl.append(numpy.array([],dtype='float32')) dx.append(numpy.array([],dtype='float32')) dy.append(numpy.array([],dtype='float32')) # Preparing fit data message if status == 0: progress = numpy.arange(nincl) if verbose: txt = 'Preparing...' sys.stdout.write(txt) sys.stdout.flush() # single processor version if status == 0:# and not cmdLine: oldtime = 0.0 for rownum in xrange(numpy.min([80,len(barytime)])): try: if barytime[rownum] - oldtime > 0.5: ftol = 1.0e-10; xtol = 1.0e-10 except: pass args = (fluxpixels[rownum,:],errpixels[rownum,:],DATx,DATy,nsrc,border,xx,yy,PRFx,PRFy,splineInterpolation, guess,ftol,xtol,focus,background,rownum,80,float(x[i]),float(y[i]),False) guess = PRFfits(args) ftol = ftolerance; xtol = tolerance; oldtime = barytime[rownum] # Fit the time series: multi-processing if status == 0 and cmdLine: anslist = [] cad1 = 0; cad2 = 50 for i in range(int(nincl/50) + 1): try: fluxp = fluxpixels[cad1:cad2,:] errp = errpixels[cad1:cad2,:] progress = numpy.arange(cad1,cad2) except: fluxp = fluxpixels[cad1:nincl,:] errp = errpixels[cad1:nincl,:] progress = numpy.arange(cad1,nincl) try: args = itertools.izip(fluxp,errp,itertools.repeat(DATx),itertools.repeat(DATy), itertools.repeat(nsrc),itertools.repeat(border),itertools.repeat(xx), itertools.repeat(yy),itertools.repeat(PRFx),itertools.repeat(PRFy), itertools.repeat(splineInterpolation),itertools.repeat(guess), itertools.repeat(ftolerance),itertools.repeat(tolerance), itertools.repeat(focus),itertools.repeat(background),progress, itertools.repeat(numpy.arange(cad1,nincl)[-1]), itertools.repeat(float(x[0])), itertools.repeat(float(y[0])),itertools.repeat(True)) p = multiprocessing.Pool() model = [0.0] model = p.imap(PRFfits,args,chunksize=1) p.close() p.join() cad1 += 50; cad2 += 50 ans = array([array(item) for item in zip(*model)]) try: anslist = numpy.concatenate((anslist,ans.transpose()),axis=0) except: anslist = ans.transpose() guess = anslist[-1] ans = anslist.transpose() except: pass # single processor version if status == 0 and not cmdLine: oldtime = 0.0; ans = [] # for rownum in xrange(1,10): for rownum in xrange(nincl): proctime = time.time() try: if barytime[rownum] - oldtime > 0.5: ftol = 1.0e-10; xtol = 1.0e-10 except: pass args = (fluxpixels[rownum,:],errpixels[rownum,:],DATx,DATy,nsrc,border,xx,yy,PRFx,PRFy,splineInterpolation, guess,ftol,xtol,focus,background,rownum,nincl,float(x[0]),float(y[0]),True) guess = PRFfits(args) ans.append(guess) ftol = ftolerance; xtol = tolerance; oldtime = barytime[rownum] ans = array(ans).transpose() # unpack the best fit parameters if status == 0: flux = []; OBJx = []; OBJy = [] na = shape(ans)[1] for i in range(nsrc): flux.append(ans[i,:]) OBJx.append(ans[nsrc+i,:]) OBJy.append(ans[nsrc*2+i,:]) try: bterms = border + 1 if bterms == 1: b = ans[nsrc*3,:] else: b = array([]) bkg = [] for i in range(na): bcoeff = array([ans[nsrc*3:nsrc*3+bterms,i],ans[nsrc*3+bterms:nsrc*3+bterms*2,i]]) bkg.append(kepfunc.polyval2d(xx,yy,bcoeff)) b = numpy.append(b,nanmean(bkg[-1].reshape(bkg[-1].size))) except: b = zeros((na)) if focus: wx = ans[-3,:]; wy = ans[-2,:]; angle = ans[-1,:] else: wx = ones((na)); wy = ones((na)); angle = zeros((na)) # constuct model PRF in detector coordinates if status == 0: residual = []; chi2 = [] for i in range(na): f = empty((nsrc)) x = empty((nsrc)) y = empty((nsrc)) for j in range(nsrc): f[j] = flux[j][i] x[j] = OBJx[j][i] y[j] = OBJy[j][i] PRFfit = kepfunc.PRF2DET(f,x,y,DATx,DATy,wx[i],wy[i],angle[i],splineInterpolation) if background and bterms == 1: PRFfit = PRFfit + b[i] if background and bterms > 1: PRFfit = PRFfit + bkg[i] # calculate residual of DATA - FIT xdim = shape(xx)[1] ydim = shape(yy)[0] DATimg = numpy.empty((ydim,xdim)) n = 0 for k in range(ydim): for j in range(xdim): DATimg[k,j] = fluxpixels[i,n] n += 1 PRFres = DATimg - PRFfit residual.append(numpy.nansum(PRFres) / npix) # calculate the sum squared difference between data and model chi2.append(abs(numpy.nansum(numpy.square(DATimg - PRFfit) / PRFfit))) # load the output arrays if status == 0: otime = barytime - bjdref otimecorr = tcorr ocadenceno = cadno opos_corr1 = poscorr1 opos_corr2 = poscorr2 oquality = qual opsf_bkg = b opsf_focus1 = wx opsf_focus2 = wy opsf_rotation = angle opsf_residual = residual opsf_chi2 = chi2 opsf_flux_err = numpy.empty((na)); opsf_flux_err.fill(numpy.nan) opsf_centr1_err = numpy.empty((na)); opsf_centr1_err.fill(numpy.nan) opsf_centr2_err = numpy.empty((na)); opsf_centr2_err.fill(numpy.nan) opsf_bkg_err = numpy.empty((na)); opsf_bkg_err.fill(numpy.nan) opsf_flux = [] opsf_centr1 = [] opsf_centr2 = [] for i in range(nsrc): opsf_flux.append(flux[i]) opsf_centr1.append(OBJx[i]) opsf_centr2.append(OBJy[i]) # load the plot arrays if status == 0: t = barytime for i in range(nsrc): fl[i] = flux[i] dx[i] = OBJx[i] dy[i] = OBJy[i] bg = b fx = wx fy = wy fa = angle rs = residual ch = chi2 # construct output primary extension if status == 0: for j in range(nsrc): hdu0 = pyfits.PrimaryHDU() for i in range(len(cards0)): if cards0[i].key not in hdu0.header.keys(): hdu0.header.update(cards0[i].key, cards0[i].value, cards0[i].comment) else: hdu0.header.cards[cards0[i].key].comment = cards0[i].comment status = kepkey.history(call,hdu0,outfile,logfile,verbose) outstr = HDUList(hdu0) # construct output light curve extension col1 = Column(name='TIME',format='D',unit='BJD - 2454833',array=otime) col2 = Column(name='TIMECORR',format='E',unit='d',array=otimecorr) col3 = Column(name='CADENCENO',format='J',array=ocadenceno) col4 = Column(name='PSF_FLUX',format='E',unit='e-/s',array=opsf_flux[j]) col5 = Column(name='PSF_FLUX_ERR',format='E',unit='e-/s',array=opsf_flux_err) col6 = Column(name='PSF_BKG',format='E',unit='e-/s/pix',array=opsf_bkg) col7 = Column(name='PSF_BKG_ERR',format='E',unit='e-/s',array=opsf_bkg_err) col8 = Column(name='PSF_CENTR1',format='E',unit='pixel',array=opsf_centr1[j]) col9 = Column(name='PSF_CENTR1_ERR',format='E',unit='pixel',array=opsf_centr1_err) col10 = Column(name='PSF_CENTR2',format='E',unit='pixel',array=opsf_centr2[j]) col11 = Column(name='PSF_CENTR2_ERR',format='E',unit='pixel',array=opsf_centr2_err) col12 = Column(name='PSF_FOCUS1',format='E',array=opsf_focus1) col13 = Column(name='PSF_FOCUS2',format='E',array=opsf_focus2) col14 = Column(name='PSF_ROTATION',format='E',unit='deg',array=opsf_rotation) col15 = Column(name='PSF_RESIDUAL',format='E',unit='e-/s',array=opsf_residual) col16 = Column(name='PSF_CHI2',format='E',array=opsf_chi2) col17 = Column(name='POS_CORR1',format='E',unit='pixel',array=opos_corr1) col18 = Column(name='POS_CORR2',format='E',unit='pixel',array=opos_corr2) col19 = Column(name='SAP_QUALITY',format='J',array=oquality) cols = ColDefs([col1,col2,col3,col4,col5,col6,col7,col8,col9,col10,col11, col12,col13,col14,col15,col16,col17,col18,col19]) hdu1 = new_table(cols) for i in range(len(cards1)): if (cards1[i].key not in hdu1.header.keys() and cards1[i].key[:4] not in ['TTYP','TFOR','TUNI','TDIS','TDIM','WCAX','1CTY', '2CTY','1CRP','2CRP','1CRV','2CRV','1CUN','2CUN', '1CDE','2CDE','1CTY','2CTY','1CDL','2CDL','11PC', '12PC','21PC','22PC']): hdu1.header.update(cards1[i].key, cards1[i].value, cards1[i].comment) outstr.append(hdu1) # construct output mask bitmap extension hdu2 = ImageHDU(maskmap) for i in range(len(cards2)): if cards2[i].key not in hdu2.header.keys(): hdu2.header.update(cards2[i].key, cards2[i].value, cards2[i].comment) else: hdu2.header.cards[cards2[i].key].comment = cards2[i].comment outstr.append(hdu2) # write output file outstr.writeto(outroot + '_' + str(j) + '.fits',checksum=True) # close input structure status = kepio.closefits(struct,logfile,verbose) # clean up x-axis unit if status == 0: barytime0 = float(int(t[0] / 100) * 100.0) t -= barytime0 t = numpy.insert(t,[0],[t[0]]) t = numpy.append(t,[t[-1]]) xlab = 'BJD $-$ %d' % barytime0 # plot the light curves if status == 0: bg = numpy.insert(bg,[0],[-1.0e10]) bg = numpy.append(bg,-1.0e10) fx = numpy.insert(fx,[0],[fx[0]]) fx = numpy.append(fx,fx[-1]) fy = numpy.insert(fy,[0],[fy[0]]) fy = numpy.append(fy,fy[-1]) fa = numpy.insert(fa,[0],[fa[0]]) fa = numpy.append(fa,fa[-1]) rs = numpy.insert(rs,[0],[-1.0e10]) rs = numpy.append(rs,-1.0e10) ch = numpy.insert(ch,[0],[-1.0e10]) ch = numpy.append(ch,-1.0e10) for i in range(nsrc): # clean up y-axis units nrm = math.ceil(math.log10(numpy.nanmax(fl[i]))) - 1.0 fl[i] /= 10**nrm if nrm == 0: ylab1 = 'e$^-$ s$^{-1}$' else: ylab1 = '10$^{%d}$ e$^-$ s$^{-1}$' % nrm xx = copy(dx[i]) yy = copy(dy[i]) ylab2 = 'offset (pixels)' # data limits xmin = numpy.nanmin(t) xmax = numpy.nanmax(t) ymin1 = numpy.nanmin(fl[i]) ymax1 = numpy.nanmax(fl[i]) ymin2 = numpy.nanmin(xx) ymax2 = numpy.nanmax(xx) ymin3 = numpy.nanmin(yy) ymax3 = numpy.nanmax(yy) ymin4 = numpy.nanmin(bg[1:-1]) ymax4 = numpy.nanmax(bg[1:-1]) ymin5 = numpy.nanmin([numpy.nanmin(fx),numpy.nanmin(fy)]) ymax5 = numpy.nanmax([numpy.nanmax(fx),numpy.nanmax(fy)]) ymin6 = numpy.nanmin(fa[1:-1]) ymax6 = numpy.nanmax(fa[1:-1]) ymin7 = numpy.nanmin(rs[1:-1]) ymax7 = numpy.nanmax(rs[1:-1]) ymin8 = numpy.nanmin(ch[1:-1]) ymax8 = numpy.nanmax(ch[1:-1]) xr = xmax - xmin yr1 = ymax1 - ymin1 yr2 = ymax2 - ymin2 yr3 = ymax3 - ymin3 yr4 = ymax4 - ymin4 yr5 = ymax5 - ymin5 yr6 = ymax6 - ymin6 yr7 = ymax7 - ymin7 yr8 = ymax8 - ymin8 fl[i] = numpy.insert(fl[i],[0],[0.0]) fl[i] = numpy.append(fl[i],0.0) # plot style try: params = {'backend': 'png', 'axes.linewidth': 2.5, 'axes.labelsize': 24, 'axes.font': 'sans-serif', 'axes.fontweight' : 'bold', 'text.fontsize': 12, 'legend.fontsize': 12, 'xtick.labelsize': 12, 'ytick.labelsize': 12} pylab.rcParams.update(params) except: pass # define size of plot on monitor screen pylab.figure(str(i+1) + ' ' + str(time.asctime(time.localtime())),figsize=[12,16]) # delete any fossil plots in the matplotlib window pylab.clf() # position first axes inside the plotting window ax = pylab.axes([0.11,0.523,0.78,0.45]) # force tick labels to be absolute rather than relative pylab.gca().xaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.gca().yaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) # no x-label pylab.setp(pylab.gca(),xticklabels=[]) # plot flux vs time ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') dt = 0 work1 = 2.0 * cadence / 86400 for j in range(1,len(t)-1): dt = t[j] - t[j-1] if dt < work1: ltime = numpy.append(ltime,t[j]) ldata = numpy.append(ldata,fl[i][j]) else: pylab.plot(ltime,ldata,color='#0000ff',linestyle='-',linewidth=1.0) ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') pylab.plot(ltime,ldata,color='#0000ff',linestyle='-',linewidth=1.0) # plot the fill color below data time series, with no data gaps pylab.fill(t,fl[i],fc='#ffff00',linewidth=0.0,alpha=0.2) # define plot x and y limits pylab.xlim(xmin - xr * 0.01, xmax + xr * 0.01) if ymin1 - yr1 * 0.01 <= 0.0: pylab.ylim(1.0e-10, ymax1 + yr1 * 0.01) else: pylab.ylim(ymin1 - yr1 * 0.01, ymax1 + yr1 * 0.01) # plot labels # pylab.xlabel(xlab, {'color' : 'k'}) try: pylab.ylabel('Source (' + ylab1 + ')', {'color' : 'k'}) except: ylab1 = '10**%d e-/s' % nrm pylab.ylabel('Source (' + ylab1 + ')', {'color' : 'k'}) # make grid on plot pylab.grid() # plot centroid tracks - position second axes inside the plotting window if focus and background: axs = [0.11,0.433,0.78,0.09] elif background or focus: axs = [0.11,0.388,0.78,0.135] else: axs = [0.11,0.253,0.78,0.27] ax1 = pylab.axes(axs) # force tick labels to be absolute rather than relative pylab.gca().xaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.gca().yaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.setp(pylab.gca(),xticklabels=[]) # plot dx vs time ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') dt = 0 work1 = 2.0 * cadence / 86400 for j in range(1,len(t)-1): dt = t[j] - t[j-1] if dt < work1: ltime = numpy.append(ltime,t[j]) ldata = numpy.append(ldata,xx[j-1]) else: ax1.plot(ltime,ldata,color='r',linestyle='-',linewidth=1.0) ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') ax1.plot(ltime,ldata,color='r',linestyle='-',linewidth=1.0) # define plot x and y limits pylab.xlim(xmin - xr * 0.01, xmax + xr * 0.01) pylab.ylim(ymin2 - yr2 * 0.03, ymax2 + yr2 * 0.03) # plot labels ax1.set_ylabel('X-' + ylab2, color='k', fontsize=11) # position second axes inside the plotting window ax2 = ax1.twinx() # force tick labels to be absolute rather than relative pylab.gca().xaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.gca().yaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.setp(pylab.gca(),xticklabels=[]) # plot dy vs time ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') dt = 0 work1 = 2.0 * cadence / 86400 for j in range(1,len(t)-1): dt = t[j] - t[j-1] if dt < work1: ltime = numpy.append(ltime,t[j]) ldata = numpy.append(ldata,yy[j-1]) else: ax2.plot(ltime,ldata,color='g',linestyle='-',linewidth=1.0) ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') ax2.plot(ltime,ldata,color='g',linestyle='-',linewidth=1.0) # define plot y limits pylab.xlim(xmin - xr * 0.01, xmax + xr * 0.01) pylab.ylim(ymin3 - yr3 * 0.03, ymax3 + yr3 * 0.03) # plot labels ax2.set_ylabel('Y-' + ylab2, color='k',fontsize=11) # background - position third axes inside the plotting window if background and focus: axs = [0.11,0.343,0.78,0.09] if background and not focus: axs = [0.11,0.253,0.78,0.135] if background: ax1 = pylab.axes(axs) # force tick labels to be absolute rather than relative pylab.gca().xaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.gca().yaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.setp(pylab.gca(),xticklabels=[]) # plot background vs time ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') dt = 0 work1 = 2.0 * cadence / 86400 for j in range(1,len(t)-1): dt = t[j] - t[j-1] if dt < work1: ltime = numpy.append(ltime,t[j]) ldata = numpy.append(ldata,bg[j]) else: ax1.plot(ltime,ldata,color='#0000ff',linestyle='-',linewidth=1.0) ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') ax1.plot(ltime,ldata,color='#0000ff',linestyle='-',linewidth=1.0) # plot the fill color below data time series, with no data gaps pylab.fill(t,bg,fc='#ffff00',linewidth=0.0,alpha=0.2) # define plot x and y limits pylab.xlim(xmin - xr * 0.01, xmax + xr * 0.01) pylab.ylim(ymin4 - yr4 * 0.03, ymax4 + yr4 * 0.03) # plot labels ax1.set_ylabel('Background \n(e$^-$ s$^{-1}$ pix$^{-1}$)', multialignment='center', color='k',fontsize=11) # make grid on plot pylab.grid() # position focus axes inside the plotting window if focus and background: axs = [0.11,0.253,0.78,0.09] if focus and not background: axs = [0.11,0.253,0.78,0.135] if focus: ax1 = pylab.axes(axs) # force tick labels to be absolute rather than relative pylab.gca().xaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.gca().yaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.setp(pylab.gca(),xticklabels=[]) # plot x-axis PSF width vs time ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') dt = 0 work1 = 2.0 * cadence / 86400 for j in range(1,len(t)-1): dt = t[j] - t[j-1] if dt < work1: ltime = numpy.append(ltime,t[j]) ldata = numpy.append(ldata,fx[j]) else: ax1.plot(ltime,ldata,color='r',linestyle='-',linewidth=1.0) ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') ax1.plot(ltime,ldata,color='r',linestyle='-',linewidth=1.0) # plot y-axis PSF width vs time ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') dt = 0 work1 = 2.0 * cadence / 86400 for j in range(1,len(t)-1): dt = t[j] - t[j-1] if dt < work1: ltime = numpy.append(ltime,t[j]) ldata = numpy.append(ldata,fy[j]) else: ax1.plot(ltime,ldata,color='g',linestyle='-',linewidth=1.0) ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') ax1.plot(ltime,ldata,color='g',linestyle='-',linewidth=1.0) # define plot x and y limits pylab.xlim(xmin - xr * 0.01, xmax + xr * 0.01) pylab.ylim(ymin5 - yr5 * 0.03, ymax5 + yr5 * 0.03) # plot labels ax1.set_ylabel('Pixel Scale\nFactor', multialignment='center', color='k',fontsize=11) # Focus rotation - position second axes inside the plotting window ax2 = ax1.twinx() # force tick labels to be absolute rather than relative pylab.gca().xaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.gca().yaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.setp(pylab.gca(),xticklabels=[]) # plot dy vs time ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') dt = 0 work1 = 2.0 * cadence / 86400 for j in range(1,len(t)-1): dt = t[j] - t[j-1] if dt < work1: ltime = numpy.append(ltime,t[j]) ldata = numpy.append(ldata,fa[j]) else: ax2.plot(ltime,ldata,color='#000080',linestyle='-',linewidth=1.0) ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') ax2.plot(ltime,ldata,color='#000080',linestyle='-',linewidth=1.0) # define plot y limits pylab.xlim(xmin - xr * 0.01, xmax + xr * 0.01) pylab.ylim(ymin6 - yr6 * 0.03, ymax6 + yr6 * 0.03) # plot labels ax2.set_ylabel('Rotation (deg)', color='k',fontsize=11) # fit residuals - position fifth axes inside the plotting window axs = [0.11,0.163,0.78,0.09] ax1 = pylab.axes(axs) # force tick labels to be absolute rather than relative pylab.gca().xaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.gca().yaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.setp(pylab.gca(),xticklabels=[]) # plot residual vs time ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') dt = 0 work1 = 2.0 * cadence / 86400 for j in range(1,len(t)-1): dt = t[j] - t[j-1] if dt < work1: ltime = numpy.append(ltime,t[j]) ldata = numpy.append(ldata,rs[j]) else: ax1.plot(ltime,ldata,color='b',linestyle='-',linewidth=1.0) ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') ax1.plot(ltime,ldata,color='b',linestyle='-',linewidth=1.0) # plot the fill color below data time series, with no data gaps pylab.fill(t,rs,fc='#ffff00',linewidth=0.0,alpha=0.2) # define plot x and y limits pylab.xlim(xmin - xr * 0.01, xmax + xr * 0.01) pylab.ylim(ymin7 - yr7 * 0.03, ymax7 + yr7 * 0.03) # plot labels ax1.set_ylabel('Residual \n(e$^-$ s$^{-1}$)', multialignment='center', color='k',fontsize=11) # make grid on plot pylab.grid() # fit chi square - position sixth axes inside the plotting window axs = [0.11,0.073,0.78,0.09] ax1 = pylab.axes(axs) # force tick labels to be absolute rather than relative pylab.gca().xaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.gca().yaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) # plot background vs time ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') dt = 0 work1 = 2.0 * cadence / 86400 for j in range(1,len(t)-1): dt = t[j] - t[j-1] if dt < work1: ltime = numpy.append(ltime,t[j]) ldata = numpy.append(ldata,ch[j]) else: ax1.plot(ltime,ldata,color='b',linestyle='-',linewidth=1.0) ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') ax1.plot(ltime,ldata,color='b',linestyle='-',linewidth=1.0) # plot the fill color below data time series, with no data gaps pylab.fill(t,ch,fc='#ffff00',linewidth=0.0,alpha=0.2) # define plot x and y limits pylab.xlim(xmin - xr * 0.01, xmax + xr * 0.01) pylab.ylim(ymin8 - yr8 * 0.03, ymax8 + yr8 * 0.03) # plot labels ax1.set_ylabel('$\chi^2$ (%d dof)' % (npix-len(guess)-1),color='k',fontsize=11) pylab.xlabel(xlab, {'color' : 'k'}) # make grid on plot pylab.grid() # render plot if status == 0: pylab.savefig(outroot + '_' + str(i) + '.png') if status == 0 and plt: if cmdLine: pylab.show(block=True) else: pylab.ion() pylab.plot([]) pylab.ioff() # stop time kepmsg.clock('\n\nKEPPRFPHOT ended at',logfile,verbose) return
def 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 kepprf_AMC(infile, rownum, columns, rows, fluxes, border, background, focus, prfdir, xtol, ftol, verbose, logfile): # input arguments status = 0 seterr(all="ignore") # open FITS file and get header info + data instr = fits.open(infile, mode='readonly', memmap=True) crval1p = instr[0].header['CRVAL1P'] crval2p = instr[0].header['CRVAL2P'] # construct inital guess vector for fit if status == 0: guess = [] try: f = fluxes.strip().split(',') x = columns.strip().split(',') y = rows.strip().split(',') for i in xrange(len(f)): f[i] = float(f[i]) except: f = fluxes x = columns y = rows nsrc = len(f) for i in xrange(nsrc): try: guess.append(float(f[i])) except: message = 'ERROR -- KEPPRF: Fluxes must be floating point numbers' status = kepmsg.err(logfile, message, verbose) if status == 0: if len(x) != nsrc or len(y) != nsrc: message = 'ERROR -- KEPFIT:FITMULTIPRF: Guesses for rows, columns and ' message += 'fluxes must have the same number of sources' status = kepmsg.err(logfile, message, verbose) if status == 0: for i in xrange(nsrc): try: guess.append(float(x[i]) + crval1p) except: message = 'ERROR -- KEPPRF: Columns must be floating point numbers' status = kepmsg.err(logfile, message, verbose) if status == 0: for i in xrange(nsrc): try: guess.append(float(y[i]) + crval2p) except: message = 'ERROR -- KEPPRF: Rows must be floating point numbers' status = kepmsg.err(logfile, message, verbose) if status == 0 and background: if border == 0: guess.append(0.0) else: for i in range((border + 1) * 2): guess.append(0.0) if status == 0 and focus: guess.append(1.0) guess.append(1.0) guess.append(0.0) # Get data from image; then close it fluxpixels = instr[0].data[:] errpixels = np.array([sqrt(val) for val in fluxpixels]) module = instr[0].header['MODULE'] output = instr[0].header['OUTPUT'] instr.close() x[0] = str(int(x[0]) + crval1p) y[0] = str(int(y[0]) + crval2p) column = int(x[0]) - 3 row = int(y[0]) - 3 ## xdim = 11 ## ydim = 11 ## npix = 121 xdim = 7 ydim = 7 npix = 49 # construct input pixel image if status == 0: flux = fluxpixels[row - crval2p:row - crval2p + ydim, column - crval1p:column - crval1p + xdim] ferr = errpixels[row - crval2p:row - crval2p + ydim, column - crval1p:column - crval1p + xdim] isize = numpy.shape(flux)[0] jsize = numpy.shape(flux)[1] flux = numpy.reshape(flux, (isize * jsize)) ferr = numpy.reshape(ferr, (isize * jsize)) DATx = arange(column, column + xdim) DATy = arange(row, row + ydim) # if numpy.nanmin > 420000.0: flux -= 420000.0 # image scale and intensity limits of pixel data if status == 0: n = 0 DATimg = empty((ydim, xdim)) ERRimg = empty((ydim, xdim)) for i in range(ydim): for j in range(xdim): DATimg[i, j] = flux[n] ERRimg[i, j] = ferr[n] n += 1 # determine suitable PRF calibration file if status == 0: if int(module) < 10: prefix = 'kplr0' else: prefix = 'kplr' prfglob = prfdir + '/' + prefix + str(module) + '.' + str( output) + '*' + '_prf.fits' try: prffile = glob.glob(prfglob)[0] except: message = 'ERROR -- KEPPRF: No PRF file found in ' + prfdir status = kepmsg.err(logfile, message, verbose) # read PRF images if status == 0: prfn = [0, 0, 0, 0, 0] crpix1p = numpy.zeros((5), dtype='float32') crpix2p = numpy.zeros((5), dtype='float32') crval1p = numpy.zeros((5), dtype='float32') crval2p = numpy.zeros((5), dtype='float32') cdelt1p = numpy.zeros((5), dtype='float32') cdelt2p = numpy.zeros((5), dtype='float32') for i in range(5): prfn[i], crpix1p[i], crpix2p[i], crval1p[i], crval2p[i], cdelt1p[i], cdelt2p[i], status \ = kepio.readPRFimage(prffile,i+1,logfile,verbose) prfn = array(prfn) PRFx = arange(0.5, shape(prfn[0])[1] + 0.5) PRFy = arange(0.5, shape(prfn[0])[0] + 0.5) PRFx = (PRFx - size(PRFx) / 2) * cdelt1p[0] PRFy = (PRFy - size(PRFy) / 2) * cdelt2p[0] # interpolate the calibrated PRF shape to the target position if status == 0: prf = zeros(shape(prfn[0]), dtype='float32') prfWeight = zeros((5), dtype='float32') for i in xrange(5): prfWeight[i] = sqrt((column - crval1p[i])**2 + (row - crval2p[i])**2) if prfWeight[i] == 0.0: prfWeight[i] = 1.0e-6 prf = prf + prfn[i] / prfWeight[i] prf = prf / nansum(prf) / cdelt1p[0] / cdelt2p[0] # location of the data image centered on the PRF image (in PRF pixel units) if status == 0: prfDimY = int(ydim / cdelt1p[0]) prfDimX = int(xdim / cdelt2p[0]) PRFy0 = (shape(prf)[0] - prfDimY) / 2 PRFx0 = (shape(prf)[1] - prfDimX) / 2 # interpolation function over the PRF if status == 0: splineInterpolation = scipy.interpolate.RectBivariateSpline( PRFx, PRFy, prf) # construct mesh for background model if status == 0 and background: bx = numpy.arange(1., float(xdim + 1)) by = numpy.arange(1., float(ydim + 1)) xx, yy = numpy.meshgrid(numpy.linspace(bx.min(), bx.max(), xdim), numpy.linspace(by.min(), by.max(), ydim)) # fit PRF model to pixel data if status == 0: if focus and background: args = (DATx, DATy, DATimg, ERRimg, nsrc, border, xx, yy, splineInterpolation, float(x[0]), float(y[0])) ans = fmin_powell(kepfunc.PRFwithFocusAndBackground, guess, args=args, xtol=xtol, ftol=ftol, disp=False) elif focus and not background: args = (DATx, DATy, DATimg, ERRimg, nsrc, splineInterpolation, float(x[0]), float(y[0])) ans = fmin_powell(kepfunc.PRFwithFocus, guess, args=args, xtol=xtol, ftol=ftol, disp=False) elif background and not focus: args = (DATx, DATy, DATimg, ERRimg, nsrc, border, xx, yy, splineInterpolation, float(x[0]), float(y[0])) ans = fmin_powell(kepfunc.PRFwithBackground, guess, args=args, xtol=xtol, ftol=ftol, disp=False) else: args = (DATx, DATy, DATimg, ERRimg, nsrc, splineInterpolation, float(x[0]), float(y[0])) ans = fmin_powell(kepfunc.PRF, guess, args=args, xtol=xtol, ftol=ftol, disp=False) # pad the PRF data if the PRF array is smaller than the data array if status == 0: flux = [] OBJx = [] OBJy = [] PRFmod = numpy.zeros((prfDimY, prfDimX)) if PRFy0 < 0 or PRFx0 < 0.0: PRFmod = numpy.zeros((prfDimY, prfDimX)) superPRF = zeros((prfDimY + 1, prfDimX + 1)) superPRF[abs(PRFy0):abs(PRFy0) + shape(prf)[0], abs(PRFx0):abs(PRFx0) + shape(prf)[1]] = prf prf = superPRF * 1.0 PRFy0 = 0 PRFx0 = 0 # rotate the PRF model around its center if focus: angle = ans[-1] prf = rotate(prf, -angle, reshape=False, mode='nearest') # iterate through the sources in the best fit PSF model for i in range(nsrc): flux.append(ans[i]) OBJx.append(ans[nsrc + i]) OBJy.append(ans[nsrc * 2 + i]) # calculate best-fit model y = (OBJy[i] - mean(DATy)) / cdelt1p[0] x = (OBJx[i] - mean(DATx)) / cdelt2p[0] prfTmp = shift(prf, [y, x], order=3, mode='constant') prfTmp = prfTmp[PRFy0:PRFy0 + prfDimY, PRFx0:PRFx0 + prfDimX] PRFmod = PRFmod + prfTmp * flux[i] wx = 1.0 wy = 1.0 angle = 0 b = 0.0 # write out best fit parameters if verbose: txt = 'Flux = %10.2f e-/s ' % flux[i] txt += 'X = %9.4f pix ' % OBJx[i] txt += 'Y = %9.4f pix ' % OBJy[i] kepmsg.log(logfile, txt, True) if background: bterms = border + 1 if bterms == 1: b = ans[nsrc * 3] else: bcoeff = array([ ans[nsrc * 3:nsrc * 3 + bterms], ans[nsrc * 3 + bterms:nsrc * 3 + bterms * 2] ]) bkg = kepfunc.polyval2d(xx, yy, bcoeff) b = nanmean(bkg.reshape(bkg.size)) txt = '\n Mean background = %.2f e-/s' % b if verbose and background: kepmsg.log(logfile, txt, True) if focus: wx = ans[-3] wy = ans[-2] angle = ans[-1] if verbose and focus: if not background: kepmsg.log(logfile, '', True) kepmsg.log(logfile, ' X/Y focus factors = %.3f/%.3f' % (wx, wy), True) kepmsg.log(logfile, 'PRF rotation angle = %.2f deg' % angle, True) # measure flux fraction and contamination if status == 0: PRFall = kepfunc.PRF2DET(flux, OBJx, OBJy, DATx, DATy, wx, wy, angle, splineInterpolation) PRFone = kepfunc.PRF2DET([flux[0]], [OBJx[0]], [OBJy[0]], DATx, DATy, wx, wy, angle, splineInterpolation) # constuct model PRF in detector coordinates if status == 0: PRFfit = PRFall + 0.0 if background and bterms == 1: PRFfit = PRFall + b if background and bterms > 1: PRFfit = PRFall + bkg # calculate residual of DATA - FIT if status == 0: PRFres = DATimg - PRFfit FLUXres = numpy.nansum(PRFres) / npix # calculate the sum squared difference between data and model if status == 0: Pearson = abs(numpy.nansum(numpy.square(DATimg - PRFfit) / PRFfit)) Chi2 = numpy.nansum( numpy.square(DATimg - PRFfit) / numpy.square(ERRimg)) DegOfFreedom = npix - len(guess) - 1 if verbose: try: kepmsg.log(logfile, '\n Residual flux = %.2f e-/s' % FLUXres, True) kepmsg.log( logfile, 'Pearson\'s chi^2 test = %d for %d dof' % (Pearson, DegOfFreedom), True) except: pass kepmsg.log( logfile, ' Chi^2 test = %d for %d dof' % (Chi2, DegOfFreedom), True) result = np.array([flux[0], OBJx[0], OBJy[0]]) return result
def kepprf(infile, columns, rows, fluxes, rownum=0, border=0, background=0, focus=0, prfdir='../KeplerPRF', xtol=1.e-6, ftol=1.e-6, imscale='linear', cmap='YlOrBr', lcolor='k', acolor='b', logfile='kepcrowd.log', CrowdTPF=np.nan, srcinfo=None, **kwargs): # log the call hashline = '----------------------------------------------------------------------------' kepmsg.log(logfile, hashline, True) call = 'KEPPRF -- ' call += 'infile=' + infile + ' ' call += 'rownum=' + str(rownum) + ' ' call += 'columns=' + columns + ' ' call += 'rows=' + rows + ' ' call += 'fluxes=' + fluxes + ' ' call += 'border=' + str(border) + ' ' bground = 'n' if (background): bground = 'y' call += 'background=' + bground + ' ' focs = 'n' if (focus): focs = 'y' call += 'focus=' + focs + ' ' call += 'prfdir=' + prfdir + ' ' call += 'xtol=' + str(xtol) + ' ' call += 'ftol=' + str(xtol) + ' ' call += 'logfile=' + logfile kepmsg.log(logfile, call + '\n', True) guess = [] try: f = fluxes.strip().split(',') x = columns.strip().split(',') y = rows.strip().split(',') for i in range(len(f)): f[i] = float(f[i]) except: f = fluxes x = columns y = rows nsrc = len(f) for i in range(nsrc): try: guess.append(float(f[i])) except: message = 'ERROR -- KEPPRF: Fluxes must be floating point numbers' kepmsg.err(logfile, message, True) return None if len(x) != nsrc or len(y) != nsrc: message = 'ERROR -- KEPFIT:FITMULTIPRF: Guesses for rows, columns and ' message += 'fluxes must have the same number of sources' kepmsg.err(logfile, message, True) return None for i in range(nsrc): try: guess.append(float(x[i])) except: message = 'ERROR -- KEPPRF: Columns must be floating point numbers' kepmsg.err(logfile, message, True) return None for i in range(nsrc): try: guess.append(float(y[i])) except: message = 'ERROR -- KEPPRF: Rows must be floating point numbers' kepmsg.err(logfile, message, True) return None if background: if border == 0: guess.append(0.0) else: for i in range((border + 1) * 2): guess.append(0.0) if focus: guess.append(1.0) guess.append(1.0) guess.append(0.0) # open TPF FITS file try: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, barytime, status = \ kepio.readTPF(infile,'TIME',logfile,True) except: message = 'ERROR -- KEPPRF: is %s a Target Pixel File? ' % infile kepmsg.err(logfile, message, True) return None kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, tcorr, status = \ kepio.readTPF(infile,'TIMECORR',logfile,True) kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, cadno, status = \ kepio.readTPF(infile,'CADENCENO',logfile,True) kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, fluxpixels, status = \ kepio.readTPF(infile,'FLUX',logfile,True) kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, errpixels, status = \ kepio.readTPF(infile,'FLUX_ERR',logfile,True) kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, qual, status = \ kepio.readTPF(infile,'QUALITY',logfile,True) # read mask defintion data from TPF file maskimg, pixcoord1, pixcoord2, status = kepio.readMaskDefinition( infile, logfile, True) npix = np.size(np.nonzero(maskimg)[0]) print('') print(' KepID: %s' % kepid) print(' BJD: %.2f' % (barytime[rownum - 1] + 2454833.0)) print(' RA (J2000): %s' % ra) print('Dec (J2000): %s' % dec) print(' KepMag: %s' % kepmag) print(' SkyGroup: %2s' % skygroup) print(' Season: %2s' % str(season)) print(' Channel: %2s' % channel) print(' Module: %2s' % module) print(' Output: %1s' % output) print('') # is this a good row with finite timestamp and pixels? if not np.isfinite(barytime[rownum - 1]) or np.nansum( fluxpixels[rownum - 1, :]) == np.nan: message = 'ERROR -- KEPFIELD: Row ' + str( rownum) + ' is a bad quality timestamp' status = kepmsg.err(logfile, message, True) # construct input pixel image flux = fluxpixels[rownum - 1, :] ferr = errpixels[rownum - 1, :] DATx = np.arange(column, column + xdim) DATy = np.arange(row, row + ydim) # image scale and intensity limits of pixel data n = 0 DATimg = np.empty((ydim, xdim)) ERRimg = np.empty((ydim, xdim)) for i in range(ydim): for j in range(xdim): DATimg[i, j] = flux[n] ERRimg[i, j] = ferr[n] n += 1 # determine suitable PRF calibration file if int(module) < 10: prefix = 'kplr0' else: prefix = 'kplr' prfglob = prfdir + '/' + prefix + str(module) + '.' + str( output) + '*' + '_prf.fits' try: prffile = glob.glob(prfglob)[0] except: message = 'ERROR -- KEPPRF: No PRF file found in ' + prfdir kepmsg.err(logfile, message, True) return None # read PRF images prfn = [0, 0, 0, 0, 0] crpix1p = np.zeros((5), dtype='float32') crpix2p = np.zeros((5), dtype='float32') crval1p = np.zeros((5), dtype='float32') crval2p = np.zeros((5), dtype='float32') cdelt1p = np.zeros((5), dtype='float32') cdelt2p = np.zeros((5), dtype='float32') for i in range(5): prfn[i], crpix1p[i], crpix2p[i], crval1p[i], crval2p[i], cdelt1p[i], cdelt2p[i], status \ = kepio.readPRFimage(prffile,i+1,logfile,True) prfn = np.array(prfn) PRFx = np.arange(0.5, np.shape(prfn[0])[1] + 0.5) PRFy = np.arange(0.5, np.shape(prfn[0])[0] + 0.5) PRFx = (PRFx - np.size(PRFx) / 2) * cdelt1p[0] PRFy = (PRFy - np.size(PRFy) / 2) * cdelt2p[0] # interpolate the calibrated PRF shape to the target position prf = np.zeros(np.shape(prfn[0]), dtype='float32') prfWeight = np.zeros((5), dtype='float32') for i in range(5): prfWeight[i] = np.sqrt((column - crval1p[i])**2 + (row - crval2p[i])**2) if prfWeight[i] == 0.0: prfWeight[i] = 1.0e-6 prf = prf + prfn[i] / prfWeight[i] prf = prf / np.nansum(prf) / cdelt1p[0] / cdelt2p[0] # location of the data image centered on the PRF image (in PRF pixel units) prfDimY = int(ydim / cdelt1p[0]) prfDimX = int(xdim / cdelt2p[0]) PRFy0 = (np.shape(prf)[0] - prfDimY) / 2 PRFx0 = (np.shape(prf)[1] - prfDimX) / 2 # interpolation function over the PRF splineInterpolation = scipy.interpolate.RectBivariateSpline( PRFx, PRFy, prf) # construct mesh for background model if background: bx = np.arange(1., float(xdim + 1)) by = np.arange(1., float(ydim + 1)) xx, yy = np.meshgrid(np.linspace(bx.min(), bx.max(), xdim), np.linspace(by.min(), by.max(), ydim)) # fit PRF model to pixel data start = time.time() if focus and background: args = (DATx, DATy, DATimg, ERRimg, nsrc, border, xx, yy, splineInterpolation, float(x[0]), float(y[0])) ans = fmin_powell(kepfunc.PRFwithFocusAndBackground, guess, args=args, xtol=xtol, ftol=ftol, disp=False) elif focus and not background: args = (DATx, DATy, DATimg, ERRimg, nsrc, splineInterpolation, float(x[0]), float(y[0])) ans = fmin_powell(kepfunc.PRFwithFocus, guess, args=args, xtol=xtol, ftol=ftol, disp=False) elif background and not focus: args = (DATx, DATy, DATimg, ERRimg, nsrc, border, xx, yy, splineInterpolation, float(x[0]), float(y[0])) ans = fmin_powell(kepfunc.PRFwithBackground, guess, args=args, xtol=xtol, ftol=ftol, disp=False) else: args = (DATx, DATy, DATimg, ERRimg, nsrc, splineInterpolation, float(x[0]), float(y[0])) ans = fmin_powell(kepfunc.PRF, guess, args=args, xtol=xtol, ftol=ftol, disp=False) kepmsg.log(logfile, 'Convergence time = %.2fs\n' % (time.time() - start), True) # pad the PRF data if the PRF array is smaller than the data array flux = [] OBJx = [] OBJy = [] PRFmod = np.zeros((prfDimY, prfDimX)) if PRFy0 < 0 or PRFx0 < 0.0: PRFmod = np.zeros((prfDimY, prfDimX)) superPRF = np.zeros((prfDimY + 1, prfDimX + 1)) superPRF[np.abs(PRFy0):np.abs(PRFy0) + np.shape(prf)[0], np.abs(PRFx0):np.abs(PRFx0) + np.shape(prf)[1]] = prf prf = superPRF * 1.0 PRFy0 = 0 PRFx0 = 0 # rotate the PRF model around its center if focus: angle = ans[-1] prf = rotate(prf, -angle, reshape=False, mode='nearest') # iterate through the sources in the best fit PSF model for i in range(nsrc): flux.append(ans[i]) OBJx.append(ans[nsrc + i]) OBJy.append(ans[nsrc * 2 + i]) # calculate best-fit model y = (OBJy[i] - np.mean(DATy)) / cdelt1p[0] x = (OBJx[i] - np.mean(DATx)) / cdelt2p[0] prfTmp = shift(prf, [y, x], order=3, mode='constant') prfTmp = prfTmp[PRFy0:PRFy0 + prfDimY, PRFx0:PRFx0 + prfDimX] PRFmod = PRFmod + prfTmp * flux[i] wx = 1.0 wy = 1.0 angle = 0 b = 0.0 # write out best fit parameters txt = 'Flux = %10.2f e-/s ' % flux[i] txt += 'X = %9.4f pix ' % OBJx[i] txt += 'Y = %9.4f pix ' % OBJy[i] kepmsg.log(logfile, txt, True) if background: bterms = border + 1 if bterms == 1: b = ans[nsrc * 3] else: bcoeff = np.array([ ans[nsrc * 3:nsrc * 3 + bterms], ans[nsrc * 3 + bterms:nsrc * 3 + bterms * 2] ]) bkg = kepfunc.polyval2d(xx, yy, bcoeff) b = nanmean(bkg.reshape(bkg.size)) txt = '\n Mean background = %.2f e-/s' % b kepmsg.log(logfile, txt, True) if focus: wx = ans[-3] wy = ans[-2] angle = ans[-1] if not background: kepmsg.log(logfile, '', True) kepmsg.log(logfile, ' X/Y focus factors = %.3f/%.3f' % (wx, wy), True) kepmsg.log(logfile, 'PRF rotation angle = %.2f deg' % angle, True) # measure flux fraction and contamination # LUGER: This looks horribly bugged. ``PRFall`` is certainly NOT the sum of the all the sources. # Check out my comments in ``kepfunc.py``. PRFall = kepfunc.PRF2DET(flux, OBJx, OBJy, DATx, DATy, wx, wy, angle, splineInterpolation) PRFone = kepfunc.PRF2DET([flux[0]], [OBJx[0]], [OBJy[0]], DATx, DATy, wx, wy, angle, splineInterpolation) # LUGER: Add up contaminant fluxes PRFcont = np.zeros_like(PRFone) for ncont in range(1, len(flux)): PRFcont += kepfunc.PRF2DET([flux[ncont]], [OBJx[ncont]], [OBJy[ncont]], DATx, DATy, wx, wy, angle, splineInterpolation) PRFcont[np.where(PRFcont < 0)] = 0 FluxInMaskAll = np.nansum(PRFall) FluxInMaskOne = np.nansum(PRFone) FluxInAperAll = 0.0 FluxInAperOne = 0.0 FluxInAperAllTrue = 0.0 for i in range(1, ydim): for j in range(1, xdim): if kepstat.bitInBitmap(maskimg[i, j], 2): FluxInAperAll += PRFall[i, j] FluxInAperOne += PRFone[i, j] FluxInAperAllTrue += PRFone[i, j] + PRFcont[i, j] FluxFraction = FluxInAperOne / flux[0] try: Contamination = (FluxInAperAll - FluxInAperOne) / FluxInAperAll except: Contamination = 0.0 # LUGER: Pixel crowding metrics Crowding = PRFone / (PRFone + PRFcont) Crowding[np.where(Crowding < 0)] = np.nan # LUGER: Optimal aperture crowding metric CrowdAper = FluxInAperOne / FluxInAperAllTrue kepmsg.log( logfile, '\n Total flux in mask = %.2f e-/s' % FluxInMaskAll, True) kepmsg.log( logfile, ' Target flux in mask = %.2f e-/s' % FluxInMaskOne, True) kepmsg.log( logfile, ' Total flux in aperture = %.2f e-/s' % FluxInAperAll, True) kepmsg.log( logfile, ' Target flux in aperture = %.2f e-/s' % FluxInAperOne, True) kepmsg.log( logfile, ' Target flux fraction in aperture = %.2f%%' % (FluxFraction * 100.0), True) kepmsg.log( logfile, 'Contamination fraction in aperture = %.2f%%' % (Contamination * 100.0), True) kepmsg.log(logfile, ' Crowding metric in aperture = %.4f' % (CrowdAper), True) kepmsg.log(logfile, ' Crowding metric from TPF = %.4f' % (CrowdTPF), True) # constuct model PRF in detector coordinates PRFfit = PRFall + 0.0 if background and bterms == 1: PRFfit = PRFall + b if background and bterms > 1: PRFfit = PRFall + bkg # calculate residual of DATA - FIT PRFres = DATimg - PRFfit FLUXres = np.nansum(PRFres) / npix # calculate the sum squared difference between data and model Pearson = np.abs(np.nansum(np.square(DATimg - PRFfit) / PRFfit)) Chi2 = np.nansum(np.square(DATimg - PRFfit) / np.square(ERRimg)) DegOfFreedom = npix - len(guess) - 1 try: kepmsg.log(logfile, '\n Residual flux = %.2f e-/s' % FLUXres, True) kepmsg.log( logfile, 'Pearson\'s chi^2 test = %d for %d dof' % (Pearson, DegOfFreedom), True) except: pass kepmsg.log(logfile, ' Chi^2 test = %d for %d dof' % (Chi2, DegOfFreedom), True) # image scale and intensity limits for plotting images imgdat_pl, zminfl, zmaxfl = kepplot.intScale2D(DATimg, imscale) imgprf_pl, zminpr, zmaxpr = kepplot.intScale2D(PRFmod, imscale) imgfit_pl, zminfi, zmaxfi = kepplot.intScale2D(PRFfit, imscale) imgres_pl, zminre, zmaxre = kepplot.intScale2D(PRFres, 'linear') if imscale == 'linear': zmaxpr *= 0.9 elif imscale == 'logarithmic': zmaxpr = np.max(zmaxpr) zminpr = zmaxpr / 2 # plot pl.figure(figsize=[12, 10]) pl.clf() # data plotimage(imgdat_pl, zminfl, zmaxfl, 1, row, column, xdim, ydim, 0.07, 0.58, 'observation', cmap, lcolor) pl.text(0.05, 0.05, 'CROWDSAP: %.4f' % CrowdTPF, horizontalalignment='left', verticalalignment='center', fontsize=18, fontweight=500, color=lcolor, transform=pl.gca().transAxes) kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 1, acolor, '--', 0.5) kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 2, acolor, '-', 3.0) # model plotimage(imgprf_pl, zminpr, zmaxpr, 2, row, column, xdim, ydim, 0.445, 0.58, 'model', cmap, lcolor) pl.text(0.05, 0.05, 'Crowding: %.4f' % CrowdAper, horizontalalignment='left', verticalalignment='center', fontsize=18, fontweight=500, color=lcolor, transform=pl.gca().transAxes) for x, y in zip(OBJx, OBJy): pl.scatter(x, y, marker='x', color='w') kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 1, acolor, '--', 0.5) kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 2, acolor, '-', 3.0) if srcinfo is not None: kepid, sx, sy, kepmag = srcinfo for i in range(len(sx) - 1, -1, -1): if kepid[i] != 0 and kepmag[i] != 0.0: size = max( np.array([ 80.0, 80.0 + (2.5**(18.0 - max(12.0, float(kepmag[i])))) * 250.0 ])) pl.scatter(sx[i], sy[i], s=size, facecolors='g', edgecolors='k', alpha=0.1) else: pl.scatter(sx[i], sy[i], s=80, facecolors='r', edgecolors='k', alpha=0.1) # binned model plotimage(imgfit_pl, zminfl, zmaxfl, 3, row, column, xdim, ydim, 0.07, 0.18, 'fit', cmap, lcolor, crowd=Crowding) kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 1, acolor, '--', 0.5) kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 2, acolor, '-', 3.0) # residuals reslim = max(np.abs(zminre), np.abs(zmaxre)) plotimage(imgres_pl, -reslim, reslim, 4, row, column, xdim, ydim, 0.445, 0.18, 'residual', 'coolwarm', lcolor) kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 1, acolor, '--', 0.5) kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 2, acolor, '-', 3.0) # plot data color bar barwin = pl.axes([0.84, 0.18, 0.03, 0.8]) if imscale == 'linear': brange = np.arange(zminfl, zmaxfl, (zmaxfl - zminfl) / 1000) elif imscale == 'logarithmic': brange = np.arange(10.0**zminfl, 10.0**zmaxfl, (10.0**zmaxfl - 10.0**zminfl) / 1000) elif imscale == 'squareroot': brange = np.arange(zminfl**2, zmaxfl**2, (zmaxfl**2 - zminfl**2) / 1000) if imscale == 'linear': barimg = np.resize(brange, (1000, 1)) elif imscale == 'logarithmic': barimg = np.log10(np.resize(brange, (1000, 1))) elif imscale == 'squareroot': barimg = np.sqrt(np.resize(brange, (1000, 1))) try: nrm = len(str(int(np.nanmax(brange)))) - 1 except: nrm = 0 brange = brange / 10**nrm pl.imshow(barimg, aspect='auto', interpolation='nearest', origin='lower', vmin=np.nanmin(barimg), vmax=np.nanmax(barimg), extent=(0.0, 1.0, brange[0], brange[-1]), cmap=cmap) barwin.yaxis.tick_right() barwin.yaxis.set_label_position('right') barwin.yaxis.set_major_locator(MaxNLocator(7)) pl.gca().yaxis.set_major_formatter(pl.ScalarFormatter(useOffset=False)) pl.gca().set_autoscale_on(False) pl.setp(pl.gca(), xticklabels=[], xticks=[]) pl.ylabel('Flux (10$^%d$ e$^-$ s$^{-1}$)' % nrm) pl.setp(barwin.get_yticklabels(), 'rotation', 90) barwin.yaxis.set_major_formatter(FormatStrFormatter('%.1f')) # plot residual color bar barwin = pl.axes([0.07, 0.08, 0.75, 0.03]) brange = np.arange(-reslim, reslim, reslim / 500) barimg = np.resize(brange, (1, 1000)) pl.imshow(barimg, aspect='auto', interpolation='nearest', origin='lower', vmin=np.nanmin(barimg), vmax=np.nanmax(barimg), extent=(brange[0], brange[-1], 0.0, 1.0), cmap='coolwarm') barwin.xaxis.set_major_locator(MaxNLocator(7)) pl.gca().xaxis.set_major_formatter(pl.ScalarFormatter(useOffset=False)) pl.gca().set_autoscale_on(False) pl.setp(pl.gca(), yticklabels=[], yticks=[]) pl.xlabel('Residuals (e$^-$ s$^{-1}$)') barwin.xaxis.set_major_formatter(FormatStrFormatter('%.1f')) # render plot pl.show(block=True) pl.close() # stop time kepmsg.clock('\nKEPPRF ended at', logfile, True) return Crowding
def kepprfphot(infile,outroot,columns,rows,fluxes,border,background,focus,prfdir,ranges, tolerance,ftolerance,qualflags,plt,clobber,verbose,logfile,status,cmdLine=False): # input arguments status = 0 seterr(all="ignore") # log the call hashline = '----------------------------------------------------------------------------' kepmsg.log(logfile,hashline,verbose) call = 'KEPPRFPHOT -- ' call += 'infile='+infile+' ' call += 'outroot='+outroot+' ' call += 'columns='+columns+' ' call += 'rows='+rows+' ' call += 'fluxes='+fluxes+' ' call += 'border='+str(border)+' ' bground = 'n' if (background): bground = 'y' call += 'background='+bground+' ' focs = 'n' if (focus): focs = 'y' call += 'focus='+focs+' ' call += 'prfdir='+prfdir+' ' call += 'ranges='+ranges+' ' call += 'xtol='+str(tolerance)+' ' call += 'ftol='+str(ftolerance)+' ' quality = 'n' if (qualflags): quality = 'y' call += 'qualflags='+quality+' ' plotit = 'n' if (plt): plotit = 'y' call += 'plot='+plotit+' ' overwrite = 'n' if (clobber): overwrite = 'y' call += 'clobber='+overwrite+ ' ' chatter = 'n' if (verbose): chatter = 'y' call += 'verbose='+chatter+' ' call += 'logfile='+logfile kepmsg.log(logfile,call+'\n',verbose) # test log file logfile = kepmsg.test(logfile) # start time kepmsg.clock('KEPPRFPHOT started at',logfile,verbose) # number of sources if status == 0: work = fluxes.strip() work = re.sub(' ',',',work) work = re.sub(';',',',work) nsrc = len(work.split(',')) # construct inital guess vector for fit if status == 0: guess = [] try: f = fluxes.strip().split(',') x = columns.strip().split(',') y = rows.strip().split(',') for i in range(len(f)): f[i] = float(f[i]) except: f = fluxes x = columns y = rows nsrc = len(f) for i in range(nsrc): try: guess.append(float(f[i])) except: message = 'ERROR -- KEPPRF: Fluxes must be floating point numbers' status = kepmsg.err(logfile,message,verbose) if status == 0: if len(x) != nsrc or len(y) != nsrc: message = 'ERROR -- KEPFIT:FITMULTIPRF: Guesses for rows, columns and ' message += 'fluxes must have the same number of sources' status = kepmsg.err(logfile,message,verbose) if status == 0: for i in range(nsrc): try: guess.append(float(x[i])) except: message = 'ERROR -- KEPPRF: Columns must be floating point numbers' status = kepmsg.err(logfile,message,verbose) if status == 0: for i in range(nsrc): try: guess.append(float(y[i])) except: message = 'ERROR -- KEPPRF: Rows must be floating point numbers' status = kepmsg.err(logfile,message,verbose) if status == 0 and background: if border == 0: guess.append(0.0) else: for i in range((border+1)*2): guess.append(0.0) if status == 0 and focus: guess.append(1.0); guess.append(1.0); guess.append(0.0) # clobber output file for i in range(nsrc): outfile = '%s_%d.fits' % (outroot, i) if clobber: status = kepio.clobber(outfile,logfile,verbose) if kepio.fileexists(outfile): message = 'ERROR -- KEPPRFPHOT: ' + outfile + ' exists. Use --clobber' status = kepmsg.err(logfile,message,verbose) # open TPF FITS file if status == 0: try: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, barytime, status = \ kepio.readTPF(infile,'TIME',logfile,verbose) except: message = 'ERROR -- KEPPRFPHOT: is %s a Target Pixel File? ' % infile status = kepmsg.err(logfile,message,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, tcorr, status = \ kepio.readTPF(infile,'TIMECORR',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, cadno, status = \ kepio.readTPF(infile,'CADENCENO',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, fluxpixels, status = \ kepio.readTPF(infile,'FLUX',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, errpixels, status = \ kepio.readTPF(infile,'FLUX_ERR',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, poscorr1, status = \ kepio.readTPF(infile,'POS_CORR1',logfile,verbose) if status != 0: poscorr1 = numpy.zeros((len(barytime)),dtype='float32') poscorr1[:] = numpy.nan status = 0 if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, poscorr2, status = \ kepio.readTPF(infile,'POS_CORR2',logfile,verbose) if status != 0: poscorr2 = numpy.zeros((len(barytime)),dtype='float32') poscorr2[:] = numpy.nan status = 0 if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, qual, status = \ kepio.readTPF(infile,'QUALITY',logfile,verbose) if status == 0: struct, status = kepio.openfits(infile,'readonly',logfile,verbose) if status == 0: tstart, tstop, bjdref, cadence, status = kepio.timekeys(struct,infile,logfile,verbose,status) # input file keywords and mask map if status == 0: cards0 = struct[0].header.cards cards1 = struct[1].header.cards cards2 = struct[2].header.cards maskmap = copy(struct[2].data) npix = numpy.size(numpy.nonzero(maskmap)[0]) # print target data if status == 0 and verbose: print('') print((' KepID: %s' % kepid)) print((' RA (J2000): %s' % ra)) print(('Dec (J2000): %s' % dec)) print((' KepMag: %s' % kepmag)) print((' SkyGroup: %2s' % skygroup)) print((' Season: %2s' % str(season))) print((' Channel: %2s' % channel)) print((' Module: %2s' % module)) print((' Output: %1s' % output)) print('') # determine suitable PRF calibration file if status == 0: if int(module) < 10: prefix = 'kplr0' else: prefix = 'kplr' prfglob = prfdir + '/' + prefix + str(module) + '.' + str(output) + '*' + '_prf.fits' try: prffile = glob.glob(prfglob)[0] except: message = 'ERROR -- KEPPRFPHOT: No PRF file found in ' + prfdir status = kepmsg.err(logfile,message,verbose) # read PRF images if status == 0: prfn = [0,0,0,0,0] crpix1p = numpy.zeros((5),dtype='float32') crpix2p = numpy.zeros((5),dtype='float32') crval1p = numpy.zeros((5),dtype='float32') crval2p = numpy.zeros((5),dtype='float32') cdelt1p = numpy.zeros((5),dtype='float32') cdelt2p = numpy.zeros((5),dtype='float32') for i in range(5): prfn[i], crpix1p[i], crpix2p[i], crval1p[i], crval2p[i], cdelt1p[i], cdelt2p[i], status \ = kepio.readPRFimage(prffile,i+1,logfile,verbose) PRFx = arange(0.5,shape(prfn[0])[1]+0.5) PRFy = arange(0.5,shape(prfn[0])[0]+0.5) PRFx = (PRFx - size(PRFx) / 2) * cdelt1p[0] PRFy = (PRFy - size(PRFy) / 2) * cdelt2p[0] # interpolate the calibrated PRF shape to the target position if status == 0: prf = zeros(shape(prfn[0]),dtype='float32') prfWeight = zeros((5),dtype='float32') for i in range(5): prfWeight[i] = sqrt((column - crval1p[i])**2 + (row - crval2p[i])**2) if prfWeight[i] == 0.0: prfWeight[i] = 1.0e6 prf = prf + prfn[i] / prfWeight[i] prf = prf / nansum(prf) prf = prf / cdelt1p[0] / cdelt2p[0] # location of the data image centered on the PRF image (in PRF pixel units) if status == 0: prfDimY = ydim / cdelt1p[0] prfDimX = xdim / cdelt2p[0] PRFy0 = (shape(prf)[0] - prfDimY) / 2 PRFx0 = (shape(prf)[1] - prfDimX) / 2 # construct input pixel image if status == 0: DATx = arange(column,column+xdim) DATy = arange(row,row+ydim) # interpolation function over the PRF if status == 0: splineInterpolation = scipy.interpolate.RectBivariateSpline(PRFx,PRFy,prf,kx=3,ky=3) # construct mesh for background model if status == 0: bx = numpy.arange(1.,float(xdim+1)) by = numpy.arange(1.,float(ydim+1)) xx, yy = numpy.meshgrid(numpy.linspace(bx.min(), bx.max(), xdim), numpy.linspace(by.min(), by.max(), ydim)) # Get time ranges for new photometry, flag good data if status == 0: barytime += bjdref tstart,tstop,status = kepio.timeranges(ranges,logfile,verbose) incl = numpy.zeros((len(barytime)),dtype='int') for rownum in range(len(barytime)): for winnum in range(len(tstart)): if barytime[rownum] >= tstart[winnum] and \ barytime[rownum] <= tstop[winnum] and \ (qual[rownum] == 0 or qualflags) and \ numpy.isfinite(barytime[rownum]) and \ numpy.isfinite(numpy.nansum(fluxpixels[rownum,:])): incl[rownum] = 1 if not numpy.in1d(1,incl): message = 'ERROR -- KEPPRFPHOT: No legal data within the range ' + ranges status = kepmsg.err(logfile,message,verbose) # filter out bad data if status == 0: n = 0 nincl = (incl == 1).sum() tim = zeros((nincl),'float64') tco = zeros((nincl),'float32') cad = zeros((nincl),'float32') flu = zeros((nincl,len(fluxpixels[0])),'float32') fer = zeros((nincl,len(fluxpixels[0])),'float32') pc1 = zeros((nincl),'float32') pc2 = zeros((nincl),'float32') qua = zeros((nincl),'float32') for rownum in range(len(barytime)): if incl[rownum] == 1: tim[n] = barytime[rownum] tco[n] = tcorr[rownum] cad[n] = cadno[rownum] flu[n,:] = fluxpixels[rownum] fer[n,:] = errpixels[rownum] pc1[n] = poscorr1[rownum] pc2[n] = poscorr2[rownum] qua[n] = qual[rownum] n += 1 barytime = tim * 1.0 tcorr = tco * 1.0 cadno = cad * 1.0 fluxpixels = flu * 1.0 errpixels = fer * 1.0 poscorr1 = pc1 * 1.0 poscorr2 = pc2 * 1.0 qual = qua * 1.0 # initialize plot arrays if status == 0: t = numpy.array([],dtype='float64') fl = []; dx = []; dy = []; bg = []; fx = []; fy = []; fa = []; rs = []; ch = [] for i in range(nsrc): fl.append(numpy.array([],dtype='float32')) dx.append(numpy.array([],dtype='float32')) dy.append(numpy.array([],dtype='float32')) # Preparing fit data message if status == 0: progress = numpy.arange(nincl) if verbose: txt = 'Preparing...' sys.stdout.write(txt) sys.stdout.flush() # single processor version if status == 0:# and not cmdLine: oldtime = 0.0 for rownum in range(numpy.min([80,len(barytime)])): try: if barytime[rownum] - oldtime > 0.5: ftol = 1.0e-10; xtol = 1.0e-10 except: pass args = (fluxpixels[rownum,:],errpixels[rownum,:],DATx,DATy,nsrc,border,xx,yy,PRFx,PRFy,splineInterpolation, guess,ftol,xtol,focus,background,rownum,80,float(x[i]),float(y[i]),False) guess = PRFfits(args) ftol = ftolerance; xtol = tolerance; oldtime = barytime[rownum] # Fit the time series: multi-processing if status == 0 and cmdLine: anslist = [] cad1 = 0; cad2 = 50 for i in range(int(nincl/50) + 1): try: fluxp = fluxpixels[cad1:cad2,:] errp = errpixels[cad1:cad2,:] progress = numpy.arange(cad1,cad2) except: fluxp = fluxpixels[cad1:nincl,:] errp = errpixels[cad1:nincl,:] progress = numpy.arange(cad1,nincl) try: args = zip(fluxp,errp,itertools.repeat(DATx),itertools.repeat(DATy), itertools.repeat(nsrc),itertools.repeat(border),itertools.repeat(xx), itertools.repeat(yy),itertools.repeat(PRFx),itertools.repeat(PRFy), itertools.repeat(splineInterpolation),itertools.repeat(guess), itertools.repeat(ftolerance),itertools.repeat(tolerance), itertools.repeat(focus),itertools.repeat(background),progress, itertools.repeat(numpy.arange(cad1,nincl)[-1]), itertools.repeat(float(x[0])), itertools.repeat(float(y[0])),itertools.repeat(True)) p = multiprocessing.Pool() model = [0.0] model = p.imap(PRFfits,args,chunksize=1) p.close() p.join() cad1 += 50; cad2 += 50 ans = array([array(item) for item in zip(*model)]) try: anslist = numpy.concatenate((anslist,ans.transpose()),axis=0) except: anslist = ans.transpose() guess = anslist[-1] ans = anslist.transpose() except: pass # single processor version if status == 0 and not cmdLine: oldtime = 0.0; ans = [] # for rownum in xrange(1,10): for rownum in range(nincl): proctime = time.time() try: if barytime[rownum] - oldtime > 0.5: ftol = 1.0e-10; xtol = 1.0e-10 except: pass args = (fluxpixels[rownum,:],errpixels[rownum,:],DATx,DATy,nsrc,border,xx,yy,PRFx,PRFy,splineInterpolation, guess,ftol,xtol,focus,background,rownum,nincl,float(x[0]),float(y[0]),True) guess = PRFfits(args) ans.append(guess) ftol = ftolerance; xtol = tolerance; oldtime = barytime[rownum] ans = array(ans).transpose() # unpack the best fit parameters if status == 0: flux = []; OBJx = []; OBJy = [] na = shape(ans)[1] for i in range(nsrc): flux.append(ans[i,:]) OBJx.append(ans[nsrc+i,:]) OBJy.append(ans[nsrc*2+i,:]) try: bterms = border + 1 if bterms == 1: b = ans[nsrc*3,:] else: b = array([]) bkg = [] for i in range(na): bcoeff = array([ans[nsrc*3:nsrc*3+bterms,i],ans[nsrc*3+bterms:nsrc*3+bterms*2,i]]) bkg.append(kepfunc.polyval2d(xx,yy,bcoeff)) b = numpy.append(b,nanmean(bkg[-1].reshape(bkg[-1].size))) except: b = zeros((na)) if focus: wx = ans[-3,:]; wy = ans[-2,:]; angle = ans[-1,:] else: wx = ones((na)); wy = ones((na)); angle = zeros((na)) # constuct model PRF in detector coordinates if status == 0: residual = []; chi2 = [] for i in range(na): f = empty((nsrc)) x = empty((nsrc)) y = empty((nsrc)) for j in range(nsrc): f[j] = flux[j][i] x[j] = OBJx[j][i] y[j] = OBJy[j][i] PRFfit = kepfunc.PRF2DET(f,x,y,DATx,DATy,wx[i],wy[i],angle[i],splineInterpolation) if background and bterms == 1: PRFfit = PRFfit + b[i] if background and bterms > 1: PRFfit = PRFfit + bkg[i] # calculate residual of DATA - FIT xdim = shape(xx)[1] ydim = shape(yy)[0] DATimg = numpy.empty((ydim,xdim)) n = 0 for k in range(ydim): for j in range(xdim): DATimg[k,j] = fluxpixels[i,n] n += 1 PRFres = DATimg - PRFfit residual.append(numpy.nansum(PRFres) / npix) # calculate the sum squared difference between data and model chi2.append(abs(numpy.nansum(numpy.square(DATimg - PRFfit) / PRFfit))) # load the output arrays if status == 0: otime = barytime - bjdref otimecorr = tcorr ocadenceno = cadno opos_corr1 = poscorr1 opos_corr2 = poscorr2 oquality = qual opsf_bkg = b opsf_focus1 = wx opsf_focus2 = wy opsf_rotation = angle opsf_residual = residual opsf_chi2 = chi2 opsf_flux_err = numpy.empty((na)); opsf_flux_err.fill(numpy.nan) opsf_centr1_err = numpy.empty((na)); opsf_centr1_err.fill(numpy.nan) opsf_centr2_err = numpy.empty((na)); opsf_centr2_err.fill(numpy.nan) opsf_bkg_err = numpy.empty((na)); opsf_bkg_err.fill(numpy.nan) opsf_flux = [] opsf_centr1 = [] opsf_centr2 = [] for i in range(nsrc): opsf_flux.append(flux[i]) opsf_centr1.append(OBJx[i]) opsf_centr2.append(OBJy[i]) # load the plot arrays if status == 0: t = barytime for i in range(nsrc): fl[i] = flux[i] dx[i] = OBJx[i] dy[i] = OBJy[i] bg = b fx = wx fy = wy fa = angle rs = residual ch = chi2 # construct output primary extension if status == 0: for j in range(nsrc): hdu0 = pyfits.PrimaryHDU() for i in range(len(cards0)): if cards0[i].key not in list(hdu0.header.keys()): hdu0.header.update(cards0[i].key, cards0[i].value, cards0[i].comment) else: hdu0.header.cards[cards0[i].key].comment = cards0[i].comment status = kepkey.history(call,hdu0,outfile,logfile,verbose) outstr = HDUList(hdu0) # construct output light curve extension col1 = Column(name='TIME',format='D',unit='BJD - 2454833',array=otime) col2 = Column(name='TIMECORR',format='E',unit='d',array=otimecorr) col3 = Column(name='CADENCENO',format='J',array=ocadenceno) col4 = Column(name='PSF_FLUX',format='E',unit='e-/s',array=opsf_flux[j]) col5 = Column(name='PSF_FLUX_ERR',format='E',unit='e-/s',array=opsf_flux_err) col6 = Column(name='PSF_BKG',format='E',unit='e-/s/pix',array=opsf_bkg) col7 = Column(name='PSF_BKG_ERR',format='E',unit='e-/s',array=opsf_bkg_err) col8 = Column(name='PSF_CENTR1',format='E',unit='pixel',array=opsf_centr1[j]) col9 = Column(name='PSF_CENTR1_ERR',format='E',unit='pixel',array=opsf_centr1_err) col10 = Column(name='PSF_CENTR2',format='E',unit='pixel',array=opsf_centr2[j]) col11 = Column(name='PSF_CENTR2_ERR',format='E',unit='pixel',array=opsf_centr2_err) col12 = Column(name='PSF_FOCUS1',format='E',array=opsf_focus1) col13 = Column(name='PSF_FOCUS2',format='E',array=opsf_focus2) col14 = Column(name='PSF_ROTATION',format='E',unit='deg',array=opsf_rotation) col15 = Column(name='PSF_RESIDUAL',format='E',unit='e-/s',array=opsf_residual) col16 = Column(name='PSF_CHI2',format='E',array=opsf_chi2) col17 = Column(name='POS_CORR1',format='E',unit='pixel',array=opos_corr1) col18 = Column(name='POS_CORR2',format='E',unit='pixel',array=opos_corr2) col19 = Column(name='SAP_QUALITY',format='J',array=oquality) cols = ColDefs([col1,col2,col3,col4,col5,col6,col7,col8,col9,col10,col11, col12,col13,col14,col15,col16,col17,col18,col19]) hdu1 = new_table(cols) for i in range(len(cards1)): if (cards1[i].key not in list(hdu1.header.keys()) and cards1[i].key[:4] not in ['TTYP','TFOR','TUNI','TDIS','TDIM','WCAX','1CTY', '2CTY','1CRP','2CRP','1CRV','2CRV','1CUN','2CUN', '1CDE','2CDE','1CTY','2CTY','1CDL','2CDL','11PC', '12PC','21PC','22PC']): hdu1.header.update(cards1[i].key, cards1[i].value, cards1[i].comment) outstr.append(hdu1) # construct output mask bitmap extension hdu2 = ImageHDU(maskmap) for i in range(len(cards2)): if cards2[i].key not in list(hdu2.header.keys()): hdu2.header.update(cards2[i].key, cards2[i].value, cards2[i].comment) else: hdu2.header.cards[cards2[i].key].comment = cards2[i].comment outstr.append(hdu2) # write output file outstr.writeto(outroot + '_' + str(j) + '.fits',checksum=True) # close input structure status = kepio.closefits(struct,logfile,verbose) # clean up x-axis unit if status == 0: barytime0 = float(int(t[0] / 100) * 100.0) t -= barytime0 t = numpy.insert(t,[0],[t[0]]) t = numpy.append(t,[t[-1]]) xlab = 'BJD $-$ %d' % barytime0 # plot the light curves if status == 0: bg = numpy.insert(bg,[0],[-1.0e10]) bg = numpy.append(bg,-1.0e10) fx = numpy.insert(fx,[0],[fx[0]]) fx = numpy.append(fx,fx[-1]) fy = numpy.insert(fy,[0],[fy[0]]) fy = numpy.append(fy,fy[-1]) fa = numpy.insert(fa,[0],[fa[0]]) fa = numpy.append(fa,fa[-1]) rs = numpy.insert(rs,[0],[-1.0e10]) rs = numpy.append(rs,-1.0e10) ch = numpy.insert(ch,[0],[-1.0e10]) ch = numpy.append(ch,-1.0e10) for i in range(nsrc): # clean up y-axis units nrm = math.ceil(math.log10(numpy.nanmax(fl[i]))) - 1.0 fl[i] /= 10**nrm if nrm == 0: ylab1 = 'e$^-$ s$^{-1}$' else: ylab1 = '10$^{%d}$ e$^-$ s$^{-1}$' % nrm xx = copy(dx[i]) yy = copy(dy[i]) ylab2 = 'offset (pixels)' # data limits xmin = numpy.nanmin(t) xmax = numpy.nanmax(t) ymin1 = numpy.nanmin(fl[i]) ymax1 = numpy.nanmax(fl[i]) ymin2 = numpy.nanmin(xx) ymax2 = numpy.nanmax(xx) ymin3 = numpy.nanmin(yy) ymax3 = numpy.nanmax(yy) ymin4 = numpy.nanmin(bg[1:-1]) ymax4 = numpy.nanmax(bg[1:-1]) ymin5 = numpy.nanmin([numpy.nanmin(fx),numpy.nanmin(fy)]) ymax5 = numpy.nanmax([numpy.nanmax(fx),numpy.nanmax(fy)]) ymin6 = numpy.nanmin(fa[1:-1]) ymax6 = numpy.nanmax(fa[1:-1]) ymin7 = numpy.nanmin(rs[1:-1]) ymax7 = numpy.nanmax(rs[1:-1]) ymin8 = numpy.nanmin(ch[1:-1]) ymax8 = numpy.nanmax(ch[1:-1]) xr = xmax - xmin yr1 = ymax1 - ymin1 yr2 = ymax2 - ymin2 yr3 = ymax3 - ymin3 yr4 = ymax4 - ymin4 yr5 = ymax5 - ymin5 yr6 = ymax6 - ymin6 yr7 = ymax7 - ymin7 yr8 = ymax8 - ymin8 fl[i] = numpy.insert(fl[i],[0],[0.0]) fl[i] = numpy.append(fl[i],0.0) # plot style try: params = {'backend': 'png', 'axes.linewidth': 2.5, 'axes.labelsize': 24, 'axes.font': 'sans-serif', 'axes.fontweight' : 'bold', 'text.fontsize': 12, 'legend.fontsize': 12, 'xtick.labelsize': 12, 'ytick.labelsize': 12} pylab.rcParams.update(params) except: pass # define size of plot on monitor screen pylab.figure(str(i+1) + ' ' + str(time.asctime(time.localtime())),figsize=[12,16]) # delete any fossil plots in the matplotlib window pylab.clf() # position first axes inside the plotting window ax = pylab.axes([0.11,0.523,0.78,0.45]) # force tick labels to be absolute rather than relative pylab.gca().xaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.gca().yaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) # no x-label pylab.setp(pylab.gca(),xticklabels=[]) # plot flux vs time ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') dt = 0 work1 = 2.0 * cadence / 86400 for j in range(1,len(t)-1): dt = t[j] - t[j-1] if dt < work1: ltime = numpy.append(ltime,t[j]) ldata = numpy.append(ldata,fl[i][j]) else: pylab.plot(ltime,ldata,color='#0000ff',linestyle='-',linewidth=1.0) ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') pylab.plot(ltime,ldata,color='#0000ff',linestyle='-',linewidth=1.0) # plot the fill color below data time series, with no data gaps pylab.fill(t,fl[i],fc='#ffff00',linewidth=0.0,alpha=0.2) # define plot x and y limits pylab.xlim(xmin - xr * 0.01, xmax + xr * 0.01) if ymin1 - yr1 * 0.01 <= 0.0: pylab.ylim(1.0e-10, ymax1 + yr1 * 0.01) else: pylab.ylim(ymin1 - yr1 * 0.01, ymax1 + yr1 * 0.01) # plot labels # pylab.xlabel(xlab, {'color' : 'k'}) try: pylab.ylabel('Source (' + ylab1 + ')', {'color' : 'k'}) except: ylab1 = '10**%d e-/s' % nrm pylab.ylabel('Source (' + ylab1 + ')', {'color' : 'k'}) # make grid on plot pylab.grid() # plot centroid tracks - position second axes inside the plotting window if focus and background: axs = [0.11,0.433,0.78,0.09] elif background or focus: axs = [0.11,0.388,0.78,0.135] else: axs = [0.11,0.253,0.78,0.27] ax1 = pylab.axes(axs) # force tick labels to be absolute rather than relative pylab.gca().xaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.gca().yaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.setp(pylab.gca(),xticklabels=[]) # plot dx vs time ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') dt = 0 work1 = 2.0 * cadence / 86400 for j in range(1,len(t)-1): dt = t[j] - t[j-1] if dt < work1: ltime = numpy.append(ltime,t[j]) ldata = numpy.append(ldata,xx[j-1]) else: ax1.plot(ltime,ldata,color='r',linestyle='-',linewidth=1.0) ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') ax1.plot(ltime,ldata,color='r',linestyle='-',linewidth=1.0) # define plot x and y limits pylab.xlim(xmin - xr * 0.01, xmax + xr * 0.01) pylab.ylim(ymin2 - yr2 * 0.03, ymax2 + yr2 * 0.03) # plot labels ax1.set_ylabel('X-' + ylab2, color='k', fontsize=11) # position second axes inside the plotting window ax2 = ax1.twinx() # force tick labels to be absolute rather than relative pylab.gca().xaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.gca().yaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.setp(pylab.gca(),xticklabels=[]) # plot dy vs time ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') dt = 0 work1 = 2.0 * cadence / 86400 for j in range(1,len(t)-1): dt = t[j] - t[j-1] if dt < work1: ltime = numpy.append(ltime,t[j]) ldata = numpy.append(ldata,yy[j-1]) else: ax2.plot(ltime,ldata,color='g',linestyle='-',linewidth=1.0) ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') ax2.plot(ltime,ldata,color='g',linestyle='-',linewidth=1.0) # define plot y limits pylab.xlim(xmin - xr * 0.01, xmax + xr * 0.01) pylab.ylim(ymin3 - yr3 * 0.03, ymax3 + yr3 * 0.03) # plot labels ax2.set_ylabel('Y-' + ylab2, color='k',fontsize=11) # background - position third axes inside the plotting window if background and focus: axs = [0.11,0.343,0.78,0.09] if background and not focus: axs = [0.11,0.253,0.78,0.135] if background: ax1 = pylab.axes(axs) # force tick labels to be absolute rather than relative pylab.gca().xaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.gca().yaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.setp(pylab.gca(),xticklabels=[]) # plot background vs time ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') dt = 0 work1 = 2.0 * cadence / 86400 for j in range(1,len(t)-1): dt = t[j] - t[j-1] if dt < work1: ltime = numpy.append(ltime,t[j]) ldata = numpy.append(ldata,bg[j]) else: ax1.plot(ltime,ldata,color='#0000ff',linestyle='-',linewidth=1.0) ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') ax1.plot(ltime,ldata,color='#0000ff',linestyle='-',linewidth=1.0) # plot the fill color below data time series, with no data gaps pylab.fill(t,bg,fc='#ffff00',linewidth=0.0,alpha=0.2) # define plot x and y limits pylab.xlim(xmin - xr * 0.01, xmax + xr * 0.01) pylab.ylim(ymin4 - yr4 * 0.03, ymax4 + yr4 * 0.03) # plot labels ax1.set_ylabel('Background \n(e$^-$ s$^{-1}$ pix$^{-1}$)', multialignment='center', color='k',fontsize=11) # make grid on plot pylab.grid() # position focus axes inside the plotting window if focus and background: axs = [0.11,0.253,0.78,0.09] if focus and not background: axs = [0.11,0.253,0.78,0.135] if focus: ax1 = pylab.axes(axs) # force tick labels to be absolute rather than relative pylab.gca().xaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.gca().yaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.setp(pylab.gca(),xticklabels=[]) # plot x-axis PSF width vs time ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') dt = 0 work1 = 2.0 * cadence / 86400 for j in range(1,len(t)-1): dt = t[j] - t[j-1] if dt < work1: ltime = numpy.append(ltime,t[j]) ldata = numpy.append(ldata,fx[j]) else: ax1.plot(ltime,ldata,color='r',linestyle='-',linewidth=1.0) ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') ax1.plot(ltime,ldata,color='r',linestyle='-',linewidth=1.0) # plot y-axis PSF width vs time ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') dt = 0 work1 = 2.0 * cadence / 86400 for j in range(1,len(t)-1): dt = t[j] - t[j-1] if dt < work1: ltime = numpy.append(ltime,t[j]) ldata = numpy.append(ldata,fy[j]) else: ax1.plot(ltime,ldata,color='g',linestyle='-',linewidth=1.0) ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') ax1.plot(ltime,ldata,color='g',linestyle='-',linewidth=1.0) # define plot x and y limits pylab.xlim(xmin - xr * 0.01, xmax + xr * 0.01) pylab.ylim(ymin5 - yr5 * 0.03, ymax5 + yr5 * 0.03) # plot labels ax1.set_ylabel('Pixel Scale\nFactor', multialignment='center', color='k',fontsize=11) # Focus rotation - position second axes inside the plotting window ax2 = ax1.twinx() # force tick labels to be absolute rather than relative pylab.gca().xaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.gca().yaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.setp(pylab.gca(),xticklabels=[]) # plot dy vs time ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') dt = 0 work1 = 2.0 * cadence / 86400 for j in range(1,len(t)-1): dt = t[j] - t[j-1] if dt < work1: ltime = numpy.append(ltime,t[j]) ldata = numpy.append(ldata,fa[j]) else: ax2.plot(ltime,ldata,color='#000080',linestyle='-',linewidth=1.0) ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') ax2.plot(ltime,ldata,color='#000080',linestyle='-',linewidth=1.0) # define plot y limits pylab.xlim(xmin - xr * 0.01, xmax + xr * 0.01) pylab.ylim(ymin6 - yr6 * 0.03, ymax6 + yr6 * 0.03) # plot labels ax2.set_ylabel('Rotation (deg)', color='k',fontsize=11) # fit residuals - position fifth axes inside the plotting window axs = [0.11,0.163,0.78,0.09] ax1 = pylab.axes(axs) # force tick labels to be absolute rather than relative pylab.gca().xaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.gca().yaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.setp(pylab.gca(),xticklabels=[]) # plot residual vs time ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') dt = 0 work1 = 2.0 * cadence / 86400 for j in range(1,len(t)-1): dt = t[j] - t[j-1] if dt < work1: ltime = numpy.append(ltime,t[j]) ldata = numpy.append(ldata,rs[j]) else: ax1.plot(ltime,ldata,color='b',linestyle='-',linewidth=1.0) ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') ax1.plot(ltime,ldata,color='b',linestyle='-',linewidth=1.0) # plot the fill color below data time series, with no data gaps pylab.fill(t,rs,fc='#ffff00',linewidth=0.0,alpha=0.2) # define plot x and y limits pylab.xlim(xmin - xr * 0.01, xmax + xr * 0.01) pylab.ylim(ymin7 - yr7 * 0.03, ymax7 + yr7 * 0.03) # plot labels ax1.set_ylabel('Residual \n(e$^-$ s$^{-1}$)', multialignment='center', color='k',fontsize=11) # make grid on plot pylab.grid() # fit chi square - position sixth axes inside the plotting window axs = [0.11,0.073,0.78,0.09] ax1 = pylab.axes(axs) # force tick labels to be absolute rather than relative pylab.gca().xaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.gca().yaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) # plot background vs time ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') dt = 0 work1 = 2.0 * cadence / 86400 for j in range(1,len(t)-1): dt = t[j] - t[j-1] if dt < work1: ltime = numpy.append(ltime,t[j]) ldata = numpy.append(ldata,ch[j]) else: ax1.plot(ltime,ldata,color='b',linestyle='-',linewidth=1.0) ltime = numpy.array([],dtype='float64') ldata = numpy.array([],dtype='float32') ax1.plot(ltime,ldata,color='b',linestyle='-',linewidth=1.0) # plot the fill color below data time series, with no data gaps pylab.fill(t,ch,fc='#ffff00',linewidth=0.0,alpha=0.2) # define plot x and y limits pylab.xlim(xmin - xr * 0.01, xmax + xr * 0.01) pylab.ylim(ymin8 - yr8 * 0.03, ymax8 + yr8 * 0.03) # plot labels ax1.set_ylabel('$\chi^2$ (%d dof)' % (npix-len(guess)-1),color='k',fontsize=11) pylab.xlabel(xlab, {'color' : 'k'}) # make grid on plot pylab.grid() # render plot if status == 0: pylab.savefig(outroot + '_' + str(i) + '.png') if status == 0 and plt: if cmdLine: pylab.show(block=True) else: pylab.ion() pylab.plot([]) pylab.ioff() # stop time kepmsg.clock('\n\nKEPPRFPHOT ended at',logfile,verbose) return
def kepprf( infile, columns, rows, fluxes, rownum=0, border=0, background=0, focus=0, prfdir="../KeplerPRF", xtol=1.0e-6, ftol=1.0e-6, imscale="linear", cmap="YlOrBr", lcolor="k", acolor="b", logfile="kepcrowd.log", CrowdTPF=np.nan, srcinfo=None, **kwargs ): # log the call hashline = "----------------------------------------------------------------------------" kepmsg.log(logfile, hashline, True) call = "KEPPRF -- " call += "infile=" + infile + " " call += "rownum=" + str(rownum) + " " call += "columns=" + columns + " " call += "rows=" + rows + " " call += "fluxes=" + fluxes + " " call += "border=" + str(border) + " " bground = "n" if background: bground = "y" call += "background=" + bground + " " focs = "n" if focus: focs = "y" call += "focus=" + focs + " " call += "prfdir=" + prfdir + " " call += "xtol=" + str(xtol) + " " call += "ftol=" + str(xtol) + " " call += "logfile=" + logfile kepmsg.log(logfile, call + "\n", True) guess = [] try: f = fluxes.strip().split(",") x = columns.strip().split(",") y = rows.strip().split(",") for i in range(len(f)): f[i] = float(f[i]) except: f = fluxes x = columns y = rows nsrc = len(f) for i in range(nsrc): try: guess.append(float(f[i])) except: message = "ERROR -- KEPPRF: Fluxes must be floating point numbers" kepmsg.err(logfile, message, True) return None if len(x) != nsrc or len(y) != nsrc: message = "ERROR -- KEPFIT:FITMULTIPRF: Guesses for rows, columns and " message += "fluxes must have the same number of sources" kepmsg.err(logfile, message, True) return None for i in range(nsrc): try: guess.append(float(x[i])) except: message = "ERROR -- KEPPRF: Columns must be floating point numbers" kepmsg.err(logfile, message, True) return None for i in range(nsrc): try: guess.append(float(y[i])) except: message = "ERROR -- KEPPRF: Rows must be floating point numbers" kepmsg.err(logfile, message, True) return None if background: if border == 0: guess.append(0.0) else: for i in range((border + 1) * 2): guess.append(0.0) if focus: guess.append(1.0) guess.append(1.0) guess.append(0.0) # open TPF FITS file try: kepid, channel, skygroup, module, output, quarter, season, ra, dec, column, row, kepmag, xdim, ydim, barytime, status = kepio.readTPF( infile, "TIME", logfile, True ) except: message = "ERROR -- KEPPRF: is %s a Target Pixel File? " % infile kepmsg.err(logfile, message, True) return None kepid, channel, skygroup, module, output, quarter, season, ra, dec, column, row, kepmag, xdim, ydim, tcorr, status = kepio.readTPF( infile, "TIMECORR", logfile, True ) kepid, channel, skygroup, module, output, quarter, season, ra, dec, column, row, kepmag, xdim, ydim, cadno, status = kepio.readTPF( infile, "CADENCENO", logfile, True ) kepid, channel, skygroup, module, output, quarter, season, ra, dec, column, row, kepmag, xdim, ydim, fluxpixels, status = kepio.readTPF( infile, "FLUX", logfile, True ) kepid, channel, skygroup, module, output, quarter, season, ra, dec, column, row, kepmag, xdim, ydim, errpixels, status = kepio.readTPF( infile, "FLUX_ERR", logfile, True ) kepid, channel, skygroup, module, output, quarter, season, ra, dec, column, row, kepmag, xdim, ydim, qual, status = kepio.readTPF( infile, "QUALITY", logfile, True ) # read mask defintion data from TPF file maskimg, pixcoord1, pixcoord2, status = kepio.readMaskDefinition(infile, logfile, True) npix = np.size(np.nonzero(maskimg)[0]) print("") print(" KepID: %s" % kepid) print(" BJD: %.2f" % (barytime[rownum - 1] + 2454833.0)) print(" RA (J2000): %s" % ra) print("Dec (J2000): %s" % dec) print(" KepMag: %s" % kepmag) print(" SkyGroup: %2s" % skygroup) print(" Season: %2s" % str(season)) print(" Channel: %2s" % channel) print(" Module: %2s" % module) print(" Output: %1s" % output) print("") # is this a good row with finite timestamp and pixels? if not np.isfinite(barytime[rownum - 1]) or np.nansum(fluxpixels[rownum - 1, :]) == np.nan: message = "ERROR -- KEPFIELD: Row " + str(rownum) + " is a bad quality timestamp" status = kepmsg.err(logfile, message, True) # construct input pixel image flux = fluxpixels[rownum - 1, :] ferr = errpixels[rownum - 1, :] DATx = np.arange(column, column + xdim) DATy = np.arange(row, row + ydim) # image scale and intensity limits of pixel data n = 0 DATimg = np.empty((ydim, xdim)) ERRimg = np.empty((ydim, xdim)) for i in range(ydim): for j in range(xdim): DATimg[i, j] = flux[n] ERRimg[i, j] = ferr[n] n += 1 # determine suitable PRF calibration file if int(module) < 10: prefix = "kplr0" else: prefix = "kplr" prfglob = prfdir + "/" + prefix + str(module) + "." + str(output) + "*" + "_prf.fits" try: prffile = glob.glob(prfglob)[0] except: message = "ERROR -- KEPPRF: No PRF file found in " + prfdir kepmsg.err(logfile, message, True) return None # read PRF images prfn = [0, 0, 0, 0, 0] crpix1p = np.zeros((5), dtype="float32") crpix2p = np.zeros((5), dtype="float32") crval1p = np.zeros((5), dtype="float32") crval2p = np.zeros((5), dtype="float32") cdelt1p = np.zeros((5), dtype="float32") cdelt2p = np.zeros((5), dtype="float32") for i in range(5): prfn[i], crpix1p[i], crpix2p[i], crval1p[i], crval2p[i], cdelt1p[i], cdelt2p[i], status = kepio.readPRFimage( prffile, i + 1, logfile, True ) prfn = np.array(prfn) PRFx = np.arange(0.5, np.shape(prfn[0])[1] + 0.5) PRFy = np.arange(0.5, np.shape(prfn[0])[0] + 0.5) PRFx = (PRFx - np.size(PRFx) / 2) * cdelt1p[0] PRFy = (PRFy - np.size(PRFy) / 2) * cdelt2p[0] # interpolate the calibrated PRF shape to the target position prf = np.zeros(np.shape(prfn[0]), dtype="float32") prfWeight = np.zeros((5), dtype="float32") for i in range(5): prfWeight[i] = np.sqrt((column - crval1p[i]) ** 2 + (row - crval2p[i]) ** 2) if prfWeight[i] == 0.0: prfWeight[i] = 1.0e-6 prf = prf + prfn[i] / prfWeight[i] prf = prf / np.nansum(prf) / cdelt1p[0] / cdelt2p[0] # location of the data image centered on the PRF image (in PRF pixel units) prfDimY = int(ydim / cdelt1p[0]) prfDimX = int(xdim / cdelt2p[0]) PRFy0 = (np.shape(prf)[0] - prfDimY) / 2 PRFx0 = (np.shape(prf)[1] - prfDimX) / 2 # interpolation function over the PRF splineInterpolation = scipy.interpolate.RectBivariateSpline(PRFx, PRFy, prf) # construct mesh for background model if background: bx = np.arange(1.0, float(xdim + 1)) by = np.arange(1.0, float(ydim + 1)) xx, yy = np.meshgrid(np.linspace(bx.min(), bx.max(), xdim), np.linspace(by.min(), by.max(), ydim)) # fit PRF model to pixel data start = time.time() if focus and background: args = (DATx, DATy, DATimg, ERRimg, nsrc, border, xx, yy, splineInterpolation, float(x[0]), float(y[0])) ans = fmin_powell(kepfunc.PRFwithFocusAndBackground, guess, args=args, xtol=xtol, ftol=ftol, disp=False) elif focus and not background: args = (DATx, DATy, DATimg, ERRimg, nsrc, splineInterpolation, float(x[0]), float(y[0])) ans = fmin_powell(kepfunc.PRFwithFocus, guess, args=args, xtol=xtol, ftol=ftol, disp=False) elif background and not focus: args = (DATx, DATy, DATimg, ERRimg, nsrc, border, xx, yy, splineInterpolation, float(x[0]), float(y[0])) ans = fmin_powell(kepfunc.PRFwithBackground, guess, args=args, xtol=xtol, ftol=ftol, disp=False) else: args = (DATx, DATy, DATimg, ERRimg, nsrc, splineInterpolation, float(x[0]), float(y[0])) ans = fmin_powell(kepfunc.PRF, guess, args=args, xtol=xtol, ftol=ftol, disp=False) kepmsg.log(logfile, "Convergence time = %.2fs\n" % (time.time() - start), True) # pad the PRF data if the PRF array is smaller than the data array flux = [] OBJx = [] OBJy = [] PRFmod = np.zeros((prfDimY, prfDimX)) if PRFy0 < 0 or PRFx0 < 0.0: PRFmod = np.zeros((prfDimY, prfDimX)) superPRF = np.zeros((prfDimY + 1, prfDimX + 1)) superPRF[ np.abs(PRFy0) : np.abs(PRFy0) + np.shape(prf)[0], np.abs(PRFx0) : np.abs(PRFx0) + np.shape(prf)[1] ] = prf prf = superPRF * 1.0 PRFy0 = 0 PRFx0 = 0 # rotate the PRF model around its center if focus: angle = ans[-1] prf = rotate(prf, -angle, reshape=False, mode="nearest") # iterate through the sources in the best fit PSF model for i in range(nsrc): flux.append(ans[i]) OBJx.append(ans[nsrc + i]) OBJy.append(ans[nsrc * 2 + i]) # calculate best-fit model y = (OBJy[i] - np.mean(DATy)) / cdelt1p[0] x = (OBJx[i] - np.mean(DATx)) / cdelt2p[0] prfTmp = shift(prf, [y, x], order=3, mode="constant") prfTmp = prfTmp[PRFy0 : PRFy0 + prfDimY, PRFx0 : PRFx0 + prfDimX] PRFmod = PRFmod + prfTmp * flux[i] wx = 1.0 wy = 1.0 angle = 0 b = 0.0 # write out best fit parameters txt = "Flux = %10.2f e-/s " % flux[i] txt += "X = %9.4f pix " % OBJx[i] txt += "Y = %9.4f pix " % OBJy[i] kepmsg.log(logfile, txt, True) if background: bterms = border + 1 if bterms == 1: b = ans[nsrc * 3] else: bcoeff = np.array([ans[nsrc * 3 : nsrc * 3 + bterms], ans[nsrc * 3 + bterms : nsrc * 3 + bterms * 2]]) bkg = kepfunc.polyval2d(xx, yy, bcoeff) b = nanmean(bkg.reshape(bkg.size)) txt = "\n Mean background = %.2f e-/s" % b kepmsg.log(logfile, txt, True) if focus: wx = ans[-3] wy = ans[-2] angle = ans[-1] if not background: kepmsg.log(logfile, "", True) kepmsg.log(logfile, " X/Y focus factors = %.3f/%.3f" % (wx, wy), True) kepmsg.log(logfile, "PRF rotation angle = %.2f deg" % angle, True) # measure flux fraction and contamination # LUGER: This looks horribly bugged. ``PRFall`` is certainly NOT the sum of the all the sources. # Check out my comments in ``kepfunc.py``. PRFall = kepfunc.PRF2DET(flux, OBJx, OBJy, DATx, DATy, wx, wy, angle, splineInterpolation) PRFone = kepfunc.PRF2DET([flux[0]], [OBJx[0]], [OBJy[0]], DATx, DATy, wx, wy, angle, splineInterpolation) # LUGER: Add up contaminant fluxes PRFcont = np.zeros_like(PRFone) for ncont in range(1, len(flux)): PRFcont += kepfunc.PRF2DET( [flux[ncont]], [OBJx[ncont]], [OBJy[ncont]], DATx, DATy, wx, wy, angle, splineInterpolation ) PRFcont[np.where(PRFcont < 0)] = 0 FluxInMaskAll = np.nansum(PRFall) FluxInMaskOne = np.nansum(PRFone) FluxInAperAll = 0.0 FluxInAperOne = 0.0 FluxInAperAllTrue = 0.0 for i in range(1, ydim): for j in range(1, xdim): if kepstat.bitInBitmap(maskimg[i, j], 2): FluxInAperAll += PRFall[i, j] FluxInAperOne += PRFone[i, j] FluxInAperAllTrue += PRFone[i, j] + PRFcont[i, j] FluxFraction = FluxInAperOne / flux[0] try: Contamination = (FluxInAperAll - FluxInAperOne) / FluxInAperAll except: Contamination = 0.0 # LUGER: Pixel crowding metrics Crowding = PRFone / (PRFone + PRFcont) Crowding[np.where(Crowding < 0)] = np.nan # LUGER: Optimal aperture crowding metric CrowdAper = FluxInAperOne / FluxInAperAllTrue kepmsg.log(logfile, "\n Total flux in mask = %.2f e-/s" % FluxInMaskAll, True) kepmsg.log(logfile, " Target flux in mask = %.2f e-/s" % FluxInMaskOne, True) kepmsg.log(logfile, " Total flux in aperture = %.2f e-/s" % FluxInAperAll, True) kepmsg.log(logfile, " Target flux in aperture = %.2f e-/s" % FluxInAperOne, True) kepmsg.log(logfile, " Target flux fraction in aperture = %.2f%%" % (FluxFraction * 100.0), True) kepmsg.log(logfile, "Contamination fraction in aperture = %.2f%%" % (Contamination * 100.0), True) kepmsg.log(logfile, " Crowding metric in aperture = %.4f" % (CrowdAper), True) kepmsg.log(logfile, " Crowding metric from TPF = %.4f" % (CrowdTPF), True) # constuct model PRF in detector coordinates PRFfit = PRFall + 0.0 if background and bterms == 1: PRFfit = PRFall + b if background and bterms > 1: PRFfit = PRFall + bkg # calculate residual of DATA - FIT PRFres = DATimg - PRFfit FLUXres = np.nansum(PRFres) / npix # calculate the sum squared difference between data and model Pearson = np.abs(np.nansum(np.square(DATimg - PRFfit) / PRFfit)) Chi2 = np.nansum(np.square(DATimg - PRFfit) / np.square(ERRimg)) DegOfFreedom = npix - len(guess) - 1 try: kepmsg.log(logfile, "\n Residual flux = %.2f e-/s" % FLUXres, True) kepmsg.log(logfile, "Pearson's chi^2 test = %d for %d dof" % (Pearson, DegOfFreedom), True) except: pass kepmsg.log(logfile, " Chi^2 test = %d for %d dof" % (Chi2, DegOfFreedom), True) # image scale and intensity limits for plotting images imgdat_pl, zminfl, zmaxfl = kepplot.intScale2D(DATimg, imscale) imgprf_pl, zminpr, zmaxpr = kepplot.intScale2D(PRFmod, imscale) imgfit_pl, zminfi, zmaxfi = kepplot.intScale2D(PRFfit, imscale) imgres_pl, zminre, zmaxre = kepplot.intScale2D(PRFres, "linear") if imscale == "linear": zmaxpr *= 0.9 elif imscale == "logarithmic": zmaxpr = np.max(zmaxpr) zminpr = zmaxpr / 2 # plot pl.figure(figsize=[12, 10]) pl.clf() # data plotimage(imgdat_pl, zminfl, zmaxfl, 1, row, column, xdim, ydim, 0.07, 0.58, "observation", cmap, lcolor) pl.text( 0.05, 0.05, "CROWDSAP: %.4f" % CrowdTPF, horizontalalignment="left", verticalalignment="center", fontsize=18, fontweight=500, color=lcolor, transform=pl.gca().transAxes, ) kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 1, acolor, "--", 0.5) kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 2, acolor, "-", 3.0) # model plotimage(imgprf_pl, zminpr, zmaxpr, 2, row, column, xdim, ydim, 0.445, 0.58, "model", cmap, lcolor) pl.text( 0.05, 0.05, "Crowding: %.4f" % CrowdAper, horizontalalignment="left", verticalalignment="center", fontsize=18, fontweight=500, color=lcolor, transform=pl.gca().transAxes, ) for x, y in zip(OBJx, OBJy): pl.scatter(x, y, marker="x", color="w") kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 1, acolor, "--", 0.5) kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 2, acolor, "-", 3.0) if srcinfo is not None: kepid, sx, sy, kepmag = srcinfo for i in range(len(sx) - 1, -1, -1): if kepid[i] != 0 and kepmag[i] != 0.0: size = max(np.array([80.0, 80.0 + (2.5 ** (18.0 - max(12.0, float(kepmag[i])))) * 250.0])) pl.scatter(sx[i], sy[i], s=size, facecolors="g", edgecolors="k", alpha=0.1) else: pl.scatter(sx[i], sy[i], s=80, facecolors="r", edgecolors="k", alpha=0.1) # binned model plotimage(imgfit_pl, zminfl, zmaxfl, 3, row, column, xdim, ydim, 0.07, 0.18, "fit", cmap, lcolor, crowd=Crowding) kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 1, acolor, "--", 0.5) kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 2, acolor, "-", 3.0) # residuals reslim = max(np.abs(zminre), np.abs(zmaxre)) plotimage(imgres_pl, -reslim, reslim, 4, row, column, xdim, ydim, 0.445, 0.18, "residual", "coolwarm", lcolor) kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 1, acolor, "--", 0.5) kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 2, acolor, "-", 3.0) # plot data color bar barwin = pl.axes([0.84, 0.18, 0.03, 0.8]) if imscale == "linear": brange = np.arange(zminfl, zmaxfl, (zmaxfl - zminfl) / 1000) elif imscale == "logarithmic": brange = np.arange(10.0 ** zminfl, 10.0 ** zmaxfl, (10.0 ** zmaxfl - 10.0 ** zminfl) / 1000) elif imscale == "squareroot": brange = np.arange(zminfl ** 2, zmaxfl ** 2, (zmaxfl ** 2 - zminfl ** 2) / 1000) if imscale == "linear": barimg = np.resize(brange, (1000, 1)) elif imscale == "logarithmic": barimg = np.log10(np.resize(brange, (1000, 1))) elif imscale == "squareroot": barimg = np.sqrt(np.resize(brange, (1000, 1))) try: nrm = len(str(int(np.nanmax(brange)))) - 1 except: nrm = 0 brange = brange / 10 ** nrm pl.imshow( barimg, aspect="auto", interpolation="nearest", origin="lower", vmin=np.nanmin(barimg), vmax=np.nanmax(barimg), extent=(0.0, 1.0, brange[0], brange[-1]), cmap=cmap, ) barwin.yaxis.tick_right() barwin.yaxis.set_label_position("right") barwin.yaxis.set_major_locator(MaxNLocator(7)) pl.gca().yaxis.set_major_formatter(pl.ScalarFormatter(useOffset=False)) pl.gca().set_autoscale_on(False) pl.setp(pl.gca(), xticklabels=[], xticks=[]) pl.ylabel("Flux (10$^%d$ e$^-$ s$^{-1}$)" % nrm) pl.setp(barwin.get_yticklabels(), "rotation", 90) barwin.yaxis.set_major_formatter(FormatStrFormatter("%.1f")) # plot residual color bar barwin = pl.axes([0.07, 0.08, 0.75, 0.03]) brange = np.arange(-reslim, reslim, reslim / 500) barimg = np.resize(brange, (1, 1000)) pl.imshow( barimg, aspect="auto", interpolation="nearest", origin="lower", vmin=np.nanmin(barimg), vmax=np.nanmax(barimg), extent=(brange[0], brange[-1], 0.0, 1.0), cmap="coolwarm", ) barwin.xaxis.set_major_locator(MaxNLocator(7)) pl.gca().xaxis.set_major_formatter(pl.ScalarFormatter(useOffset=False)) pl.gca().set_autoscale_on(False) pl.setp(pl.gca(), yticklabels=[], yticks=[]) pl.xlabel("Residuals (e$^-$ s$^{-1}$)") barwin.xaxis.set_major_formatter(FormatStrFormatter("%.1f")) # render plot pl.show(block=True) pl.close() # stop time kepmsg.clock("\nKEPPRF ended at", logfile, True) return Crowding