def kepoutlier(infile,outfile,datacol,nsig,stepsize,npoly,niter, operation,ranges,plot,plotfit,clobber,verbose,logfile,status, cmdLine=False): # startup parameters status = 0 labelsize = 24 ticksize = 16 xsize = 16 ysize = 6 lcolor = '#0000ff' lwidth = 1.0 fcolor = '#ffff00' falpha = 0.2 # log the call hashline = '----------------------------------------------------------------------------' kepmsg.log(logfile,hashline,verbose) call = 'KEPOUTLIER -- ' call += 'infile='+infile+' ' call += 'outfile='+outfile+' ' call += 'datacol='+str(datacol)+' ' call += 'nsig='+str(nsig)+' ' call += 'stepsize='+str(stepsize)+' ' call += 'npoly='+str(npoly)+' ' call += 'niter='+str(niter)+' ' call += 'operation='+str(operation)+' ' call += 'ranges='+str(ranges)+' ' plotit = 'n' if (plot): plotit = 'y' call += 'plot='+plotit+ ' ' plotf = 'n' if (plotfit): plotf = 'y' call += 'plotfit='+plotf+ ' ' 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) # start time kepmsg.clock('KEPOUTLIER started at',logfile,verbose) # test log file logfile = kepmsg.test(logfile) # clobber output file if clobber: status = kepio.clobber(outfile,logfile,verbose) if kepio.fileexists(outfile): message = 'ERROR -- KEPOUTLIER: ' + outfile + ' exists. Use clobber=yes' status = kepmsg.err(logfile,message,verbose) # open input file if status == 0: instr, status = kepio.openfits(infile,'readonly',logfile,verbose) if status == 0: tstart, tstop, bjdref, cadence, status = kepio.timekeys(instr,infile,logfile,verbose,status) if status == 0: try: work = instr[0].header['FILEVER'] cadenom = 1.0 except: cadenom = cadence # fudge non-compliant FITS keywords with no values if status == 0: instr = kepkey.emptykeys(instr,file,logfile,verbose) # read table structure if status == 0: table, status = kepio.readfitstab(infile,instr[1],logfile,verbose) # filter input data table if status == 0: try: nanclean = instr[1].header['NANCLEAN'] except: naxis2 = 0 try: for i in range(len(table.field(0))): if numpy.isfinite(table.field('barytime')[i]) and \ numpy.isfinite(table.field(datacol)[i]): table[naxis2] = table[i] naxis2 += 1 instr[1].data = table[:naxis2] except: for i in range(len(table.field(0))): if numpy.isfinite(table.field('time')[i]) and \ numpy.isfinite(table.field(datacol)[i]): table[naxis2] = table[i] naxis2 += 1 instr[1].data = table[:naxis2] comment = 'NaN cadences removed from data' status = kepkey.new('NANCLEAN',True,comment,instr[1],outfile,logfile,verbose) # read table columns if status == 0: try: intime = instr[1].data.field('barytime') + 2.4e6 except: intime, status = kepio.readfitscol(infile,instr[1].data,'time',logfile,verbose) indata, status = kepio.readfitscol(infile,instr[1].data,datacol,logfile,verbose) if status == 0: intime = intime + bjdref indata = indata / cadenom # time ranges for region to be corrected if status == 0: t1, t2, status = kepio.timeranges(ranges,logfile,verbose) cadencelis, status = kepstat.filterOnRange(intime,t1,t2) # find limits of each time step if status == 0: tstep1 = []; tstep2 = [] work = intime[0] while work < intime[-1]: tstep1.append(work) tstep2.append(array([work+stepsize,intime[-1]],dtype='float64').min()) work += stepsize # find cadence limits of each time step if status == 0: cstep1 = []; cstep2 = [] work1 = 0; work2 = 0 for i in range(len(intime)): if intime[i] >= intime[work1] and intime[i] < intime[work1] + stepsize: work2 = i else: cstep1.append(work1) cstep2.append(work2) work1 = i; work2 = i cstep1.append(work1) cstep2.append(work2) outdata = indata * 1.0 # comment keyword in output file if status == 0: status = kepkey.history(call,instr[0],outfile,logfile,verbose) # clean up x-axis unit if status == 0: intime0 = float(int(tstart / 100) * 100.0) ptime = intime - intime0 xlab = 'BJD $-$ %d' % intime0 # clean up y-axis units if status == 0: pout = indata * 1.0 nrm = len(str(int(pout.max())))-1 pout = pout / 10**nrm ylab = '10$^%d$ e$^-$ s$^{-1}$' % nrm # data limits xmin = ptime.min() xmax = ptime.max() ymin = pout.min() ymax = pout.max() xr = xmax - xmin yr = ymax - ymin ptime = insert(ptime,[0],[ptime[0]]) ptime = append(ptime,[ptime[-1]]) pout = insert(pout,[0],[0.0]) pout = append(pout,0.0) # plot light curve if status == 0 and plot: plotLatex = True try: params = {'backend': 'png', 'axes.linewidth': 2.5, 'axes.labelsize': labelsize, 'axes.font': 'sans-serif', 'axes.fontweight' : 'bold', 'text.fontsize': 12, 'legend.fontsize': 12, 'xtick.labelsize': ticksize, 'ytick.labelsize': ticksize} rcParams.update(params) except: plotLatex = False if status == 0 and plot: pylab.figure(figsize=[xsize,ysize]) pylab.clf() # plot data ax = pylab.axes([0.06,0.1,0.93,0.87]) # 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)) # rotate y labels by 90 deg labels = ax.get_yticklabels() setp(labels, 'rotation', 90, fontsize=12) pylab.plot(ptime,pout,color=lcolor,linestyle='-',linewidth=lwidth) fill(ptime,pout,color=fcolor,linewidth=0.0,alpha=falpha) xlabel(xlab, {'color' : 'k'}) if not plotLatex: ylab = '10**%d electrons/sec' % nrm ylabel(ylab, {'color' : 'k'}) grid() # loop over each time step, fit data, determine rms if status == 0: masterfit = indata * 0.0 mastersigma = zeros(len(masterfit)) functype = 'poly' + str(npoly) for i in range(len(cstep1)): pinit = [indata[cstep1[i]:cstep2[i]+1].mean()] if npoly > 0: for j in range(npoly): pinit.append(0.0) pinit = array(pinit,dtype='float32') try: coeffs, errors, covar, iiter, sigma, chi2, dof, fit, plotx, ploty, status = \ kepfit.lsqclip(functype,pinit,intime[cstep1[i]:cstep2[i]+1]-intime[cstep1[i]], indata[cstep1[i]:cstep2[i]+1],None,nsig,nsig,niter,logfile, verbose) for j in range(len(coeffs)): masterfit[cstep1[i]:cstep2[i]+1] += coeffs[j] * \ (intime[cstep1[i]:cstep2[i]+1] - intime[cstep1[i]])**j for j in range(cstep1[i],cstep2[i]+1): mastersigma[j] = sigma if plotfit: pylab.plot(plotx+intime[cstep1[i]]-intime0,ploty / 10**nrm, 'g',lw='3') except: for j in range(cstep1[i],cstep2[i]+1): masterfit[j] = indata[j] mastersigma[j] = 1.0e10 message = 'WARNING -- KEPOUTLIER: could not fit range ' message += str(intime[cstep1[i]]) + '-' + str(intime[cstep2[i]]) kepmsg.warn(None,message) # reject outliers if status == 0: rejtime = []; rejdata = []; naxis2 = 0 for i in range(len(masterfit)): if abs(indata[i] - masterfit[i]) > nsig * mastersigma[i] and i in cadencelis: rejtime.append(intime[i]) rejdata.append(indata[i]) if operation == 'replace': [rnd] = kepstat.randarray([masterfit[i]],[mastersigma[i]]) table[naxis2] = table[i] table.field(datacol)[naxis2] = rnd naxis2 += 1 else: table[naxis2] = table[i] naxis2 += 1 instr[1].data = table[:naxis2] rejtime = array(rejtime,dtype='float64') rejdata = array(rejdata,dtype='float32') pylab.plot(rejtime-intime0,rejdata / 10**nrm,'ro') # plot ranges xlim(xmin-xr*0.01,xmax+xr*0.01) if ymin >= 0.0: ylim(ymin-yr*0.01,ymax+yr*0.01) else: ylim(1.0e-10,ymax+yr*0.01) # render plot if cmdLine: pylab.show() else: pylab.ion() pylab.plot([]) pylab.ioff() # write output file if status == 0: instr.writeto(outfile) # close input file if status == 0: status = kepio.closefits(instr,logfile,verbose) ## end time if (status == 0): message = 'KEPOUTLIER completed at' else: message = '\nKEPOUTLIER aborted at' kepmsg.clock(message,logfile,verbose)
def kepclip(infile, outfile, ranges, plot, plotcol, clobber, verbose, logfile, status, cmdLine=False): # startup parameters status = 0 labelsize = 32 ticksize = 24 xsize = 18 ysize = 10 lcolor = '#0000ff' lwidth = 1.0 fcolor = '#ffff00' falpha = 0.2 # log the call hashline = '----------------------------------------------------------------------------' kepmsg.log(logfile, hashline, verbose) call = 'KEPCLIP -- ' call += 'infile=' + infile + ' ' call += 'outfile=' + outfile + ' ' call += 'ranges=' + ranges + ' ' plotit = 'n' if (plot): plotit = 'y' call += 'plot=' + plotit + ' ' call += 'plotcol=' + plotcol + ' ' 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) # start time kepmsg.clock('KEPCLIP started at', logfile, verbose) # test log file logfile = kepmsg.test(logfile) # clobber output file if clobber: status = kepio.clobber(outfile, logfile, verbose) if kepio.fileexists(outfile): message = 'ERROR -- KEPCLIP: ' + outfile + ' exists. Use --clobber' status = kepmsg.err(logfile, message, verbose) # time ranges for region if status == 0: t1 = [] t2 = [] t1, t2, status = kepio.timeranges(ranges, logfile, verbose) # open input file if status == 0: instr, status = kepio.openfits(infile, 'readonly', logfile, verbose) tstart, tstop, bjdref, cadence, status = kepio.timekeys( instr, infile, logfile, verbose, status) if status == 0: try: work = instr[0].header['FILEVER'] cadenom = 1.0 except: cadenom = cadence # fudge non-compliant FITS keywords with no values if status == 0: instr = kepkey.emptykeys(instr, file, logfile, verbose) # input data if status == 0: table = instr[1].data # read time and flux columns if status == 0: barytime, status = kepio.readtimecol(infile, table, logfile, verbose) if status == 0: flux, status = kepio.readfitscol(infile, table, plotcol, logfile, verbose) if status == 0: barytime = barytime + bjdref if 'flux' in plotcol.lower(): flux = flux / cadenom # filter input data table if status == 0: naxis2 = 0 work1 = array([], 'float64') work2 = array([], 'float32') for i in range(len(barytime)): if (numpy.isfinite(barytime[i]) and numpy.isfinite(flux[i]) and flux[i] != 0.0): reject = False for j in range(len(t1)): if (barytime[i] >= t1[j] and barytime[i] <= t2[j]): reject = True if not reject: table[naxis2] = table[i] work1 = append(work1, barytime[i]) work2 = append(work2, flux[i]) naxis2 += 1 # comment keyword in output file if status == 0: status = kepkey.history(call, instr[0], outfile, logfile, verbose) # write output file if status == 0: instr[1].data = table[:naxis2] comment = 'NaN cadences removed from data' status = kepkey.new('NANCLEAN', True, comment, instr[1], outfile, logfile, verbose) instr.writeto(outfile) # clean up x-axis unit if status == 0: barytime0 = float(int(tstart / 100) * 100.0) barytime = work1 - barytime0 xlab = 'BJD $-$ %d' % barytime0 # clean up y-axis units if status == 0: try: nrm = len(str(int(work2.max()))) - 1 except: nrm = 0 flux = work2 / 10**nrm ylab = '10$^%d$ e$^-$ s$^{-1}$' % nrm # data limits xmin = barytime.min() xmax = barytime.max() ymin = flux.min() ymax = flux.max() xr = xmax - xmin yr = ymax - ymin # plotting arguments if status == 0 and plot: try: params = { 'backend': 'png', 'axes.linewidth': 2.5, 'axes.labelsize': labelsize, 'axes.font': 'sans-serif', 'axes.fontweight': 'bold', 'text.fontsize': 12, 'legend.fontsize': 12, 'xtick.labelsize': ticksize, 'ytick.labelsize': ticksize } rcParams.update(params) except: print('ERROR -- KEPCLIP: install latex for scientific plotting') status = 1 # clear window, plot box if status == 0 and plot: pylab.figure(figsize=[xsize, ysize]) pylab.clf() ax = pylab.axes([0.05, 0.1, 0.94, 0.88]) # 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)) # rotate y labels by 90 deg labels = ax.get_yticklabels() setp(labels, 'rotation', 90, fontsize=12) # plot line data ltime = [barytime[0]] ldata = [flux[0]] for i in range(1, len(flux)): if (barytime[i - 1] > barytime[i] - 0.025): ltime.append(barytime[i]) ldata.append(flux[i]) else: ltime = array(ltime, dtype=float64) ldata = array(ldata, dtype=float64) pylab.plot(ltime, ldata, color=lcolor, linestyle='-', linewidth=lwidth) ltime = [] ldata = [] ltime = array(ltime, dtype=float64) ldata = array(ldata, dtype=float64) pylab.plot(ltime, ldata, color=lcolor, linestyle='-', linewidth=lwidth) # plot fill data barytime = insert(barytime, [0], [barytime[0]]) barytime = append(barytime, [barytime[-1]]) flux = insert(flux, [0], [0.0]) flux = append(flux, [0.0]) fill(barytime, flux, fc=fcolor, linewidth=0.0, alpha=falpha) xlim(xmin - xr * 0.01, xmax + xr * 0.01) if ymin - yr * 0.01 <= 0.0: ylim(1.0e-10, ymax + yr * 0.01) else: ylim(ymin - yr * 0.01, ymax + yr * 0.01) xlabel(xlab, {'color': 'k'}) ylabel(ylab, {'color': 'k'}) grid() # render plot if status == 0 and plot: if cmdLine: pylab.show() else: pylab.ion() pylab.plot([]) pylab.ioff() # close input file if status == 0: status = kepio.closefits(instr, logfile, verbose) # end time if (status == 0): message = 'KEPCLIP completed at' else: message = '\nKEPCLIP aborted at' kepmsg.clock(message, logfile, verbose)
def kepdetrend(infile, outfile, datacol, errcol, ranges1, npoly1, nsig1, niter1, ranges2, npoly2, nsig2, niter2, popnans, plot, clobber, verbose, logfile, status, cmdLine=False): # startup parameters status = 0 labelsize = 24 ticksize = 16 xsize = 16 ysize = 9 lcolor = '#0000ff' lwidth = 1.0 fcolor = '#ffff00' falpha = 0.2 # log the call hashline = '----------------------------------------------------------------------------' kepmsg.log(logfile, hashline, verbose) call = 'KEPDETREND -- ' call += 'infile=' + infile + ' ' call += 'outfile=' + outfile + ' ' call += 'datacol=' + str(datacol) + ' ' call += 'errcol=' + str(errcol) + ' ' call += 'ranges1=' + str(ranges1) + ' ' call += 'npoly1=' + str(npoly1) + ' ' call += 'nsig1=' + str(nsig1) + ' ' call += 'niter1=' + str(niter1) + ' ' call += 'ranges2=' + str(ranges2) + ' ' call += 'npoly2=' + str(npoly2) + ' ' call += 'nsig2=' + str(nsig2) + ' ' call += 'niter2=' + str(niter2) + ' ' popn = 'n' if (popnans): popn = 'y' call += 'popnans=' + popn + ' ' plotit = 'n' if (plot): 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) # start time kepmsg.clock('KEPDETREND started at', logfile, verbose) # test log file logfile = kepmsg.test(logfile) # clobber output file if clobber: status = kepio.clobber(outfile, logfile, verbose) if kepio.fileexists(outfile): message = 'ERROR -- KEPDETREND: ' + outfile + ' exists. Use clobber=yes' status = kepmsg.err(logfile, message, verbose) # open input file if status == 0: instr, status = kepio.openfits(infile, 'readonly', logfile, verbose) tstart, tstop, bjdref, cadence, status = kepio.timekeys( instr, infile, logfile, verbose, status) # fudge non-compliant FITS keywords with no values if status == 0: instr = kepkey.emptykeys(instr, file, logfile, verbose) # read table structure if status == 0: table, status = kepio.readfitstab(infile, instr[1], logfile, verbose) # filter input data table if status == 0: work1 = numpy.array( [table.field('time'), table.field(datacol), table.field(errcol)]) work1 = numpy.rot90(work1, 3) work1 = work1[~numpy.isnan(work1).any(1)] # read table columns if status == 0: intime = work1[:, 2] + bjdref indata = work1[:, 1] inerr = work1[:, 0] print intime # time ranges for region 1 (region to be corrected) if status == 0: time1 = [] data1 = [] err1 = [] t1start, t1stop, status = kepio.timeranges(ranges1, logfile, verbose) if status == 0: cadencelis1, status = kepstat.filterOnRange(intime, t1start, t1stop) if status == 0: for i in range(len(cadencelis1)): time1.append(intime[cadencelis1[i]]) data1.append(indata[cadencelis1[i]]) if errcol.lower() != 'none': err1.append(inerr[cadencelis1[i]]) t0 = time1[0] time1 = array(time1, dtype='float64') - t0 data1 = array(data1, dtype='float32') if errcol.lower() != 'none': err1 = array(err1, dtype='float32') else: err1 = None # fit function to range 1 if status == 0: functype = 'poly' + str(npoly1) pinit = [data1.mean()] if npoly1 > 0: for i in range(npoly1): pinit.append(0) pinit = array(pinit, dtype='float32') coeffs, errors, covar, iiter, sigma, chi2, dof, fit, plotx1, ploty1, status = \ kepfit.lsqclip(functype,pinit,time1,data1,err1,nsig1,nsig1,niter1, logfile,verbose) fit1 = indata * 0.0 for i in range(len(coeffs)): fit1 += coeffs[i] * (intime - t0)**i for i in range(len(intime)): if i not in cadencelis1: fit1[i] = 0.0 plotx1 += t0 print coeffs # time ranges for region 2 (region that is correct) if status == 0: time2 = [] data2 = [] err2 = [] t2start, t2stop, status = kepio.timeranges(ranges2, logfile, verbose) cadencelis2, status = kepstat.filterOnRange(intime, t2start, t2stop) for i in range(len(cadencelis2)): time2.append(intime[cadencelis2[i]]) data2.append(indata[cadencelis2[i]]) if errcol.lower() != 'none': err2.append(inerr[cadencelis2[i]]) t0 = time2[0] time2 = array(time2, dtype='float64') - t0 data2 = array(data2, dtype='float32') if errcol.lower() != 'none': err2 = array(err2, dtype='float32') else: err2 = None # fit function to range 2 if status == 0: functype = 'poly' + str(npoly2) pinit = [data2.mean()] if npoly2 > 0: for i in range(npoly2): pinit.append(0) pinit = array(pinit, dtype='float32') coeffs, errors, covar, iiter, sigma, chi2, dof, fit, plotx2, ploty2, status = \ kepfit.lsqclip(functype,pinit,time2,data2,err2,nsig2,nsig2,niter2, logfile,verbose) fit2 = indata * 0.0 for i in range(len(coeffs)): fit2 += coeffs[i] * (intime - t0)**i for i in range(len(intime)): if i not in cadencelis1: fit2[i] = 0.0 plotx2 += t0 # normalize data if status == 0: outdata = indata - fit1 + fit2 if errcol.lower() != 'none': outerr = inerr * 1.0 # comment keyword in output file if status == 0: status = kepkey.history(call, instr[0], outfile, logfile, verbose) # clean up x-axis unit if status == 0: intime0 = float(int(tstart / 100) * 100.0) if intime0 < 2.4e6: intime0 += 2.4e6 ptime = intime - intime0 plotx1 = plotx1 - intime0 plotx2 = plotx2 - intime0 xlab = 'BJD $-$ %d' % intime0 # clean up y-axis units if status == 0: pout = outdata ploty1 ploty2 nrm = len(str(int(numpy.nanmax(indata)))) - 1 indata = indata / 10**nrm pout = pout / 10**nrm ploty1 = ploty1 / 10**nrm ploty2 = ploty2 / 10**nrm ylab = '10$^%d$ e$^-$ s$^{-1}$' % nrm # data limits xmin = ptime.min() xmax = ptime.max() ymin = indata.min() ymax = indata.max() omin = pout.min() omax = pout.max() xr = xmax - xmin yr = ymax - ymin oo = omax - omin ptime = insert(ptime, [0], [ptime[0]]) ptime = append(ptime, [ptime[-1]]) indata = insert(indata, [0], [0.0]) indata = append(indata, [0.0]) pout = insert(pout, [0], [0.0]) pout = append(pout, 0.0) # plot light curve if status == 0 and plot: try: params = { 'backend': 'png', 'axes.linewidth': 2.5, 'axes.labelsize': labelsize, 'axes.font': 'sans-serif', 'axes.fontweight': 'bold', 'text.fontsize': 12, 'legend.fontsize': 12, 'xtick.labelsize': ticksize, 'ytick.labelsize': ticksize } rcParams.update(params) except: pass pylab.figure(figsize=[xsize, ysize]) pylab.clf() # plot original data ax = pylab.axes([0.06, 0.523, 0.93, 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)) # rotate y labels by 90 deg labels = ax.get_yticklabels() pylab.setp(labels, 'rotation', 90, fontsize=12) pylab.plot(ptime, indata, color=lcolor, linestyle='-', linewidth=lwidth) pylab.fill(ptime, indata, color=fcolor, linewidth=0.0, alpha=falpha) pylab.plot(plotx1, ploty1, color='r', linestyle='-', linewidth=2.0) pylab.plot(plotx2, ploty2, color='g', linestyle='-', linewidth=2.0) pylab.xlim(xmin - xr * 0.01, xmax + xr * 0.01) if ymin > 0.0: pylab.ylim(ymin - yr * 0.01, ymax + yr * 0.01) else: pylab.ylim(1.0e-10, ymax + yr * 0.01) pylab.ylabel(ylab, {'color': 'k'}) pylab.grid() # plot detrended data ax = pylab.axes([0.06, 0.073, 0.93, 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)) # rotate y labels by 90 deg labels = ax.get_yticklabels() pylab.setp(labels, 'rotation', 90, fontsize=12) pylab.plot(ptime, pout, color=lcolor, linestyle='-', linewidth=lwidth) pylab.fill(ptime, pout, color=fcolor, linewidth=0.0, alpha=falpha) pylab.xlim(xmin - xr * 0.01, xmax + xr * 0.01) if ymin > 0.0: pylab.ylim(omin - oo * 0.01, omax + oo * 0.01) else: pylab.ylim(1.0e-10, omax + oo * 0.01) pylab.xlabel(xlab, {'color': 'k'}) try: pylab.ylabel(ylab, {'color': 'k'}) except: ylab = '10**%d e-/s' % nrm pylab.ylabel(ylab, {'color': 'k'}) # render plot if status == 0: if cmdLine: pylab.show() else: pylab.ion() pylab.plot([]) pylab.ioff() # write output file if status == 0 and popnans: instr[1].data.field(datacol)[good_data] = outdata instr[1].data.field(errcol)[good_data] = outerr instr[1].data.field(datacol)[bad_data] = None instr[1].data.field(errcol)[bad_data] = None instr.writeto(outfile) elif status == 0 and not popnans: for i in range(len(outdata)): instr[1].data.field(datacol)[i] = outdata[i] if errcol.lower() != 'none': instr[1].data.field(errcol)[i] = outerr[i] instr.writeto(outfile) # close input file if status == 0: status = kepio.closefits(instr, logfile, verbose) ## end time if (status == 0): message = 'KEPDETREND completed at' else: message = '\nKEPDETREND aborted at' kepmsg.clock(message, logfile, verbose)
def kepimages(infile,outfix,imtype,ranges,clobber,verbose,logfile,status): # startup parameters status = 0 # log the call hashline = '----------------------------------------------------------------------------' kepmsg.log(logfile,hashline,verbose) call = 'KEPIMAGES -- ' call += 'infile='+infile+' ' call += 'outfix='+outfix+' ' call += 'imtype='+imtype+' ' call += 'ranges='+str(ranges)+' ' 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) # start time kepmsg.clock('KEPIMAGES started at',logfile,verbose) # test log file logfile = kepmsg.test(logfile) # open input file status = 0 print ' ' instr = pyfits.open(infile,mode='readonly',memmap=True) cards0 = instr[0].header.cards cards1 = instr[1].header.cards cards2 = instr[2].header.cards # fudge non-compliant FITS keywords with no values if status == 0: instr = kepkey.emptykeys(instr,file,logfile,verbose) # ingest time series data if status == 0: time = instr[1].data.field('TIME')[:] + 2454833.0 timecorr = instr[1].data.field('TIMECORR')[:] cadenceno = instr[1].data.field('CADENCENO')[:] raw_cnts = instr[1].data.field('RAW_CNTS')[:] flux = instr[1].data.field('FLUX')[:] flux_err = instr[1].data.field('FLUX_ERR')[:] flux_bkg = instr[1].data.field('FLUX_BKG')[:] flux_bkg_err = instr[1].data.field('FLUX_BKG_ERR')[:] cosmic_rays = instr[1].data.field('COSMIC_RAYS')[:] quality = instr[1].data.field('QUALITY')[:] pos_corr1 = instr[1].data.field('POS_CORR1')[:] pos_corr2 = instr[1].data.field('POS_CORR2')[:] # choose output image if status == 0: if imtype.lower() == 'raw_cnts': outim = raw_cnts elif imtype.lower() == 'flux_err': outim = flux_err elif imtype.lower() == 'flux_bkg': outim = flux_bkg elif imtype.lower() == 'flux_bkg_err': outim = flux_bkg_err elif imtype.lower() == 'cosmic_rays': outim = cosmic_rays else: outim = flux # identify images to be exported if status == 0: tim = array([]); dat = array([]); err = array([]) tstart, tstop, status = kepio.timeranges(ranges,logfile,verbose) if status == 0: cadencelis, status = kepstat.filterOnRange(time,tstart,tstop) # provide name for each output file and clobber if file exists if status == 0: for cadence in cadencelis: outfile = outfix + '_BJD%.4f' % time[cadence] + '.fits' if clobber and status == 0: status = kepio.clobber(outfile,logfile,verbose) if kepio.fileexists(outfile) and status == 0: message = 'ERROR -- KEPIMAGES: ' + outfile + ' exists. Use --clobber' status = kepmsg.err(logfile,message,True) # construct output primary extension if status == 0: ncad = 0 for cadence in cadencelis: outfile = outfix + '_BJD%.4f' % time[cadence] + '.fits' hdu0 = pyfits.PrimaryHDU() for i in range(len(cards0)): try: 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 except: pass status = kepkey.history(call,hdu0,outfile,logfile,verbose) outstr = HDUList(hdu0) # construct output image extension hdu1 = ImageHDU(flux[cadence]) for i in range(len(cards2)): try: if cards2[i].key not in hdu1.header.keys(): hdu1.header.update(cards2[i].key, cards2[i].value, cards2[i].comment) except: pass 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','WCSN','TFIE']): hdu1.header.update(cards1[i].key, cards1[i].value, cards1[i].comment) try: int_time = cards1['INT_TIME'].value except: kepmsg.warn(logfile,'WARNING -- KEPIMAGES: cannot find INT_TIME keyword') try: frametim = cards1['FRAMETIM'].value except: kepmsg.warn(logfile,'WARNING -- KEPIMAGES: cannot find FRAMETIM keyword') try: num_frm = cards1['NUM_FRM'].value except: kepmsg.warn(logfile,'WARNING -- KEPIMAGES: cannot find NUM_FRM keyword') hdu1.header.update('EXTNAME','IMAGE','name of extension') try: hdu1.header.update('TELAPSE',frametim * num_frm,'[s] elapsed time for exposure') except: hdu1.header.update('TELAPSE',-999,'[s] elapsed time for exposure') try: hdu1.header.update('LIVETIME',int_time * num_frm,'[s] TELASPE multiplied by DEADC') except: hdu1.header.update('LIVETIME',-999,'[s] TELASPE multiplied by DEADC') try: hdu1.header.update('EXPOSURE',int_time * num_frm,'[s] time on source') except: hdu1.header.update('EXPOSURE',-999,'[s] time on source') try: hdu1.header.update('MIDTIME',time[cadence],'[BJD] mid-time of exposure') except: hdu1.header.update('MIDTIME',-999,'[BJD] mid-time of exposure') try: hdu1.header.update('TIMECORR',timecorr[cadence],'[d] barycenter - timeslice correction') except: hdu1.header.update('TIMECORR',-999,'[d] barycenter - timeslice correction') try: hdu1.header.update('CADENCEN',cadenceno[cadence],'unique cadence number') except: hdu1.header.update('CADENCEN',-999,'unique cadence number') try: hdu1.header.update('QUALITY',quality[cadence],'pixel quality flag') except: hdu1.header.update('QUALITY',-999,'pixel quality flag') try: if True in numpy.isfinite(cosmic_rays[cadence]): hdu1.header.update('COSM_RAY',True,'cosmic ray detected?') else: hdu1.header.update('COSM_RAY',False,'cosmic ray detected?') except: hdu1.header.update('COSM_RAY',-999,'cosmic ray detected?') try: pc1 = str(pos_corr1[cadence]) pc2 = str(pos_corr2[cadence]) hdu1.header.update('POSCORR1',pc1,'[pix] column position correction') hdu1.header.update('POSCORR2',pc2,'[pix] row position correction') except: hdu1.header.update('POSCORR1',-999,'[pix] column position correction') hdu1.header.update('POSCORR2',-999,'[pix] row position correction') outstr.append(hdu1) # write output file if status == 0: outstr.writeto(outfile,checksum=True) ncad += 1 txt = '\r%3d%% ' % (float(ncad) / float(len(cadencelis)) * 100.0) txt += '%s ' % outfile sys.stdout.write(txt) sys.stdout.flush() # close input structure if status == 0: status = kepio.closefits(instr,logfile,verbose) print '\n' # end time kepmsg.clock('KEPIMAGES finished at',logfile,verbose)
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 kepimages(infile,outfix,imtype,ranges,clobber,verbose,logfile,status): # startup parameters status = 0 # log the call hashline = '----------------------------------------------------------------------------' kepmsg.log(logfile,hashline,verbose) call = 'KEPIMAGES -- ' call += 'infile='+infile+' ' call += 'outfix='+outfix+' ' call += 'imtype='+imtype+' ' call += 'ranges='+str(ranges)+' ' 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) # start time kepmsg.clock('KEPIMAGES started at',logfile,verbose) # test log file logfile = kepmsg.test(logfile) # open input file status = 0 print(' ') instr = pyfits.open(infile,mode='readonly',memmap=True) cards0 = instr[0].header.cards cards1 = instr[1].header.cards cards2 = instr[2].header.cards # fudge non-compliant FITS keywords with no values if status == 0: instr = kepkey.emptykeys(instr,file,logfile,verbose) # ingest time series data if status == 0: time = instr[1].data.field('TIME')[:] + 2454833.0 timecorr = instr[1].data.field('TIMECORR')[:] cadenceno = instr[1].data.field('CADENCENO')[:] raw_cnts = instr[1].data.field('RAW_CNTS')[:] flux = instr[1].data.field('FLUX')[:] flux_err = instr[1].data.field('FLUX_ERR')[:] flux_bkg = instr[1].data.field('FLUX_BKG')[:] flux_bkg_err = instr[1].data.field('FLUX_BKG_ERR')[:] cosmic_rays = instr[1].data.field('COSMIC_RAYS')[:] quality = instr[1].data.field('QUALITY')[:] pos_corr1 = instr[1].data.field('POS_CORR1')[:] pos_corr2 = instr[1].data.field('POS_CORR2')[:] # choose output image if status == 0: if imtype.lower() == 'raw_cnts': outim = raw_cnts elif imtype.lower() == 'flux_err': outim = flux_err elif imtype.lower() == 'flux_bkg': outim = flux_bkg elif imtype.lower() == 'flux_bkg_err': outim = flux_bkg_err elif imtype.lower() == 'cosmic_rays': outim = cosmic_rays else: outim = flux # identify images to be exported if status == 0: tim = array([]); dat = array([]); err = array([]) tstart, tstop, status = kepio.timeranges(ranges,logfile,verbose) if status == 0: cadencelis, status = kepstat.filterOnRange(time,tstart,tstop) # provide name for each output file and clobber if file exists if status == 0: for cadence in cadencelis: outfile = outfix + '_BJD%.4f' % time[cadence] + '.fits' if clobber and status == 0: status = kepio.clobber(outfile,logfile,verbose) if kepio.fileexists(outfile) and status == 0: message = 'ERROR -- KEPIMAGES: ' + outfile + ' exists. Use --clobber' status = kepmsg.err(logfile,message,True) # construct output primary extension if status == 0: ncad = 0 for cadence in cadencelis: outfile = outfix + '_BJD%.4f' % time[cadence] + '.fits' hdu0 = pyfits.PrimaryHDU() for i in range(len(cards0)): try: 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 except: pass status = kepkey.history(call,hdu0,outfile,logfile,verbose) outstr = HDUList(hdu0) # construct output image extension hdu1 = ImageHDU(flux[cadence]) for i in range(len(cards2)): try: if cards2[i].key not in list(hdu1.header.keys()): hdu1.header.update(cards2[i].key, cards2[i].value, cards2[i].comment) except: pass 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','WCSN','TFIE']): hdu1.header.update(cards1[i].key, cards1[i].value, cards1[i].comment) try: int_time = cards1['INT_TIME'].value except: kepmsg.warn(logfile,'WARNING -- KEPIMAGES: cannot find INT_TIME keyword') try: frametim = cards1['FRAMETIM'].value except: kepmsg.warn(logfile,'WARNING -- KEPIMAGES: cannot find FRAMETIM keyword') try: num_frm = cards1['NUM_FRM'].value except: kepmsg.warn(logfile,'WARNING -- KEPIMAGES: cannot find NUM_FRM keyword') hdu1.header.update('EXTNAME','IMAGE','name of extension') try: hdu1.header.update('TELAPSE',frametim * num_frm,'[s] elapsed time for exposure') except: hdu1.header.update('TELAPSE',-999,'[s] elapsed time for exposure') try: hdu1.header.update('LIVETIME',int_time * num_frm,'[s] TELASPE multiplied by DEADC') except: hdu1.header.update('LIVETIME',-999,'[s] TELASPE multiplied by DEADC') try: hdu1.header.update('EXPOSURE',int_time * num_frm,'[s] time on source') except: hdu1.header.update('EXPOSURE',-999,'[s] time on source') try: hdu1.header.update('MIDTIME',time[cadence],'[BJD] mid-time of exposure') except: hdu1.header.update('MIDTIME',-999,'[BJD] mid-time of exposure') try: hdu1.header.update('TIMECORR',timecorr[cadence],'[d] barycenter - timeslice correction') except: hdu1.header.update('TIMECORR',-999,'[d] barycenter - timeslice correction') try: hdu1.header.update('CADENCEN',cadenceno[cadence],'unique cadence number') except: hdu1.header.update('CADENCEN',-999,'unique cadence number') try: hdu1.header.update('QUALITY',quality[cadence],'pixel quality flag') except: hdu1.header.update('QUALITY',-999,'pixel quality flag') try: if True in numpy.isfinite(cosmic_rays[cadence]): hdu1.header.update('COSM_RAY',True,'cosmic ray detected?') else: hdu1.header.update('COSM_RAY',False,'cosmic ray detected?') except: hdu1.header.update('COSM_RAY',-999,'cosmic ray detected?') try: pc1 = str(pos_corr1[cadence]) pc2 = str(pos_corr2[cadence]) hdu1.header.update('POSCORR1',pc1,'[pix] column position correction') hdu1.header.update('POSCORR2',pc2,'[pix] row position correction') except: hdu1.header.update('POSCORR1',-999,'[pix] column position correction') hdu1.header.update('POSCORR2',-999,'[pix] row position correction') outstr.append(hdu1) # write output file if status == 0: outstr.writeto(outfile,checksum=True) ncad += 1 txt = '\r%3d%% ' % (float(ncad) / float(len(cadencelis)) * 100.0) txt += '%s ' % outfile sys.stdout.write(txt) sys.stdout.flush() # close input structure if status == 0: status = kepio.closefits(instr,logfile,verbose) print('\n') # end time kepmsg.clock('KEPIMAGES finished at',logfile,verbose)
def kepoutlier(infile,outfile,datacol,nsig,stepsize,npoly,niter, operation,ranges,plot,plotfit,clobber,verbose,logfile,status, cmdLine=False): # startup parameters status = 0 labelsize = 24 ticksize = 16 xsize = 16 ysize = 6 lcolor = '#0000ff' lwidth = 1.0 fcolor = '#ffff00' falpha = 0.2 # log the call hashline = '----------------------------------------------------------------------------' kepmsg.log(logfile,hashline,verbose) call = 'KEPOUTLIER -- ' call += 'infile='+infile+' ' call += 'outfile='+outfile+' ' call += 'datacol='+str(datacol)+' ' call += 'nsig='+str(nsig)+' ' call += 'stepsize='+str(stepsize)+' ' call += 'npoly='+str(npoly)+' ' call += 'niter='+str(niter)+' ' call += 'operation='+str(operation)+' ' call += 'ranges='+str(ranges)+' ' plotit = 'n' if (plot): plotit = 'y' call += 'plot='+plotit+ ' ' plotf = 'n' if (plotfit): plotf = 'y' call += 'plotfit='+plotf+ ' ' 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) # start time kepmsg.clock('KEPOUTLIER started at',logfile,verbose) # test log file logfile = kepmsg.test(logfile) # clobber output file if clobber: status = kepio.clobber(outfile,logfile,verbose) if kepio.fileexists(outfile): message = 'ERROR -- KEPOUTLIER: ' + outfile + ' exists. Use clobber=yes' status = kepmsg.err(logfile,message,verbose) # open input file if status == 0: instr, status = kepio.openfits(infile,'readonly',logfile,verbose) if status == 0: tstart, tstop, bjdref, cadence, status = kepio.timekeys(instr,infile,logfile,verbose,status) if status == 0: try: work = instr[0].header['FILEVER'] cadenom = 1.0 except: cadenom = cadence # fudge non-compliant FITS keywords with no values if status == 0: instr = kepkey.emptykeys(instr,file,logfile,verbose) # read table structure if status == 0: table, status = kepio.readfitstab(infile,instr[1],logfile,verbose) # filter input data table if status == 0: try: nanclean = instr[1].header['NANCLEAN'] except: naxis2 = 0 try: for i in range(len(table.field(0))): if numpy.isfinite(table.field('barytime')[i]) and \ numpy.isfinite(table.field(datacol)[i]): table[naxis2] = table[i] naxis2 += 1 instr[1].data = table[:naxis2] except: for i in range(len(table.field(0))): if numpy.isfinite(table.field('time')[i]) and \ numpy.isfinite(table.field(datacol)[i]): table[naxis2] = table[i] naxis2 += 1 instr[1].data = table[:naxis2] comment = 'NaN cadences removed from data' status = kepkey.new('NANCLEAN',True,comment,instr[1],outfile,logfile,verbose) # read table columns if status == 0: try: intime = instr[1].data.field('barytime') + 2.4e6 except: intime, status = kepio.readfitscol(infile,instr[1].data,'time',logfile,verbose) indata, status = kepio.readfitscol(infile,instr[1].data,datacol,logfile,verbose) if status == 0: intime = intime + bjdref indata = indata / cadenom # time ranges for region to be corrected if status == 0: t1, t2, status = kepio.timeranges(ranges,logfile,verbose) cadencelis, status = kepstat.filterOnRange(intime,t1,t2) # find limits of each time step if status == 0: tstep1 = []; tstep2 = [] work = intime[0] while work < intime[-1]: tstep1.append(work) tstep2.append(array([work+stepsize,intime[-1]],dtype='float64').min()) work += stepsize # find cadence limits of each time step if status == 0: cstep1 = []; cstep2 = [] work1 = 0; work2 = 0 for i in range(len(intime)): if intime[i] >= intime[work1] and intime[i] < intime[work1] + stepsize: work2 = i else: cstep1.append(work1) cstep2.append(work2) work1 = i; work2 = i cstep1.append(work1) cstep2.append(work2) outdata = indata * 1.0 # comment keyword in output file if status == 0: status = kepkey.history(call,instr[0],outfile,logfile,verbose) # clean up x-axis unit if status == 0: intime0 = float(int(tstart / 100) * 100.0) ptime = intime - intime0 xlab = 'BJD $-$ %d' % intime0 # clean up y-axis units if status == 0: pout = indata * 1.0 nrm = len(str(int(pout.max())))-1 pout = pout / 10**nrm ylab = '10$^%d$ e$^-$ s$^{-1}$' % nrm # data limits xmin = ptime.min() xmax = ptime.max() ymin = pout.min() ymax = pout.max() xr = xmax - xmin yr = ymax - ymin ptime = insert(ptime,[0],[ptime[0]]) ptime = append(ptime,[ptime[-1]]) pout = insert(pout,[0],[0.0]) pout = append(pout,0.0) # plot light curve if status == 0 and plot: plotLatex = True try: params = {'backend': 'png', 'axes.linewidth': 2.5, 'axes.labelsize': labelsize, 'axes.font': 'sans-serif', 'axes.fontweight' : 'bold', 'text.fontsize': 12, 'legend.fontsize': 12, 'xtick.labelsize': ticksize, 'ytick.labelsize': ticksize} rcParams.update(params) except: plotLatex = False if status == 0 and plot: pylab.figure(figsize=[xsize,ysize]) pylab.clf() # plot data ax = pylab.axes([0.06,0.1,0.93,0.87]) # 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)) # rotate y labels by 90 deg labels = ax.get_yticklabels() setp(labels, 'rotation', 90, fontsize=12) pylab.plot(ptime,pout,color=lcolor,linestyle='-',linewidth=lwidth) fill(ptime,pout,color=fcolor,linewidth=0.0,alpha=falpha) xlabel(xlab, {'color' : 'k'}) if not plotLatex: ylab = '10**%d electrons/sec' % nrm ylabel(ylab, {'color' : 'k'}) grid() # loop over each time step, fit data, determine rms if status == 0: masterfit = indata * 0.0 mastersigma = zeros(len(masterfit)) functype = 'poly' + str(npoly) for i in range(len(cstep1)): pinit = [indata[cstep1[i]:cstep2[i]+1].mean()] if npoly > 0: for j in range(npoly): pinit.append(0.0) pinit = array(pinit,dtype='float32') try: coeffs, errors, covar, iiter, sigma, chi2, dof, fit, plotx, ploty, status = \ kepfit.lsqclip(functype,pinit,intime[cstep1[i]:cstep2[i]+1]-intime[cstep1[i]], indata[cstep1[i]:cstep2[i]+1],None,nsig,nsig,niter,logfile, verbose) for j in range(len(coeffs)): masterfit[cstep1[i]:cstep2[i]+1] += coeffs[j] * \ (intime[cstep1[i]:cstep2[i]+1] - intime[cstep1[i]])**j for j in range(cstep1[i],cstep2[i]+1): mastersigma[j] = sigma if plotfit: pylab.plot(plotx+intime[cstep1[i]]-intime0,ploty / 10**nrm, 'g',lw='3') except: for j in range(cstep1[i],cstep2[i]+1): masterfit[j] = indata[j] mastersigma[j] = 1.0e10 message = 'WARNING -- KEPOUTLIER: could not fit range ' message += str(intime[cstep1[i]]) + '-' + str(intime[cstep2[i]]) kepmsg.warn(None,message) # reject outliers if status == 0: rejtime = []; rejdata = []; naxis2 = 0 for i in range(len(masterfit)): if abs(indata[i] - masterfit[i]) > nsig * mastersigma[i] and i in cadencelis: rejtime.append(intime[i]) rejdata.append(indata[i]) if operation == 'replace': [rnd] = kepstat.randarray([masterfit[i]],[mastersigma[i]]) table[naxis2] = table[i] table.field(datacol)[naxis2] = rnd naxis2 += 1 else: table[naxis2] = table[i] naxis2 += 1 instr[1].data = table[:naxis2] rejtime = array(rejtime,dtype='float64') rejdata = array(rejdata,dtype='float32') pylab.plot(rejtime-intime0,rejdata / 10**nrm,'ro') # plot ranges xlim(xmin-xr*0.01,xmax+xr*0.01) if ymin >= 0.0: ylim(ymin-yr*0.01,ymax+yr*0.01) else: ylim(1.0e-10,ymax+yr*0.01) # render plot if cmdLine: pylab.show() else: pylab.ion() pylab.plot([]) pylab.ioff() # write output file if status == 0: instr.writeto(outfile) # close input file if status == 0: status = kepio.closefits(instr,logfile,verbose) # end time if (status == 0): message = 'KEPOUTLIER completed at' else: message = '\nKEPOUTLIER aborted at' kepmsg.clock(message,logfile,verbose)
def kepclip(infile,outfile,ranges,plot,plotcol,clobber,verbose,logfile,status,cmdLine=False): # startup parameters status = 0 labelsize = 32 ticksize = 24 xsize = 18 ysize = 10 lcolor = '#0000ff' lwidth = 1.0 fcolor = '#ffff00' falpha = 0.2 # log the call hashline = '----------------------------------------------------------------------------' kepmsg.log(logfile,hashline,verbose) call = 'KEPCLIP -- ' call += 'infile='+infile+' ' call += 'outfile='+outfile+' ' call += 'ranges='+ranges + ' ' plotit = 'n' if (plot): plotit = 'y' call += 'plot='+plotit+ ' ' call += 'plotcol='+plotcol+ ' ' 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) # start time kepmsg.clock('KEPCLIP started at',logfile,verbose) # test log file logfile = kepmsg.test(logfile) # clobber output file if clobber: status = kepio.clobber(outfile,logfile,verbose) if kepio.fileexists(outfile): message = 'ERROR -- KEPCLIP: ' + outfile + ' exists. Use --clobber' status = kepmsg.err(logfile,message,verbose) # time ranges for region if status == 0: t1 = []; t2 = [] t1, t2, status = kepio.timeranges(ranges,logfile,verbose) # open input file if status == 0: instr, status = kepio.openfits(infile,'readonly',logfile,verbose) tstart, tstop, bjdref, cadence, status = kepio.timekeys(instr,infile,logfile,verbose,status) if status == 0: try: work = instr[0].header['FILEVER'] cadenom = 1.0 except: cadenom = cadence # fudge non-compliant FITS keywords with no values if status == 0: instr = kepkey.emptykeys(instr,file,logfile,verbose) # input data if status == 0: table = instr[1].data # read time and flux columns if status == 0: barytime, status = kepio.readtimecol(infile,table,logfile,verbose) if status == 0: flux, status = kepio.readfitscol(infile,table,plotcol,logfile,verbose) if status == 0: barytime = barytime + bjdref if 'flux' in plotcol.lower(): flux = flux / cadenom # filter input data table if status == 0: naxis2 = 0 work1 = array([],'float64') work2 = array([],'float32') for i in range(len(barytime)): if (numpy.isfinite(barytime[i]) and numpy.isfinite(flux[i]) and flux[i] != 0.0): reject = False for j in range(len(t1)): if (barytime[i] >= t1[j] and barytime[i] <= t2[j]): reject = True if not reject: table[naxis2] = table[i] work1 = append(work1,barytime[i]) work2 = append(work2,flux[i]) naxis2 += 1 # comment keyword in output file if status == 0: status = kepkey.history(call,instr[0],outfile,logfile,verbose) # write output file if status == 0: instr[1].data = table[:naxis2] comment = 'NaN cadences removed from data' status = kepkey.new('NANCLEAN',True,comment,instr[1],outfile,logfile,verbose) instr.writeto(outfile) # clean up x-axis unit if status == 0: barytime0 = float(int(tstart / 100) * 100.0) barytime = work1 - barytime0 xlab = 'BJD $-$ %d' % barytime0 # clean up y-axis units if status == 0: try: nrm = len(str(int(work2.max())))-1 except: nrm = 0 flux = work2 / 10**nrm ylab = '10$^%d$ e$^-$ s$^{-1}$' % nrm # data limits xmin = barytime.min() xmax = barytime.max() ymin = flux.min() ymax = flux.max() xr = xmax - xmin yr = ymax - ymin # plotting arguments if status == 0 and plot: try: params = {'backend': 'png', 'axes.linewidth': 2.5, 'axes.labelsize': labelsize, 'axes.font': 'sans-serif', 'axes.fontweight' : 'bold', 'text.fontsize': 12, 'legend.fontsize': 12, 'xtick.labelsize': ticksize, 'ytick.labelsize': ticksize} rcParams.update(params) except: print 'ERROR -- KEPCLIP: install latex for scientific plotting' status = 1 # clear window, plot box if status == 0 and plot: pylab.figure(figsize=[xsize,ysize]) pylab.clf() ax = pylab.axes([0.05,0.1,0.94,0.88]) # 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)) # rotate y labels by 90 deg labels = ax.get_yticklabels() setp(labels, 'rotation', 90, fontsize=12) # plot line data ltime = [barytime[0]]; ldata = [flux[0]] for i in range(1,len(flux)): if (barytime[i-1] > barytime[i] - 0.025): ltime.append(barytime[i]) ldata.append(flux[i]) else: ltime = array(ltime, dtype=float64) ldata = array(ldata, dtype=float64) pylab.plot(ltime,ldata,color=lcolor,linestyle='-',linewidth=lwidth) ltime = []; ldata = [] ltime = array(ltime, dtype=float64) ldata = array(ldata, dtype=float64) pylab.plot(ltime,ldata,color=lcolor,linestyle='-',linewidth=lwidth) # plot fill data barytime = insert(barytime,[0],[barytime[0]]) barytime = append(barytime,[barytime[-1]]) flux = insert(flux,[0],[0.0]) flux = append(flux,[0.0]) fill(barytime,flux,fc=fcolor,linewidth=0.0,alpha=falpha) xlim(xmin-xr*0.01,xmax+xr*0.01) if ymin-yr*0.01 <= 0.0: ylim(1.0e-10,ymax+yr*0.01) else: ylim(ymin-yr*0.01,ymax+yr*0.01) xlabel(xlab, {'color' : 'k'}) ylabel(ylab, {'color' : 'k'}) grid() # render plot if status == 0 and plot: if cmdLine: pylab.show() else: pylab.ion() pylab.plot([]) pylab.ioff() # close input file if status == 0: status = kepio.closefits(instr,logfile,verbose) # end time if (status == 0): message = 'KEPCLIP completed at' else: message = '\nKEPCLIP aborted at' kepmsg.clock(message,logfile,verbose)
def kepdetrend(infile,outfile,datacol,errcol,ranges1,npoly1,nsig1,niter1, ranges2,npoly2,nsig2,niter2,popnans,plot,clobber,verbose,logfile, status,cmdLine=False): # startup parameters status = 0 labelsize = 24 ticksize = 16 xsize = 16 ysize = 9 lcolor = '#0000ff' lwidth = 1.0 fcolor = '#ffff00' falpha = 0.2 # log the call hashline = '----------------------------------------------------------------------------' kepmsg.log(logfile,hashline,verbose) call = 'KEPDETREND -- ' call += 'infile='+infile+' ' call += 'outfile='+outfile+' ' call += 'datacol='+str(datacol)+' ' call += 'errcol='+str(errcol)+' ' call += 'ranges1='+str(ranges1)+' ' call += 'npoly1='+str(npoly1)+' ' call += 'nsig1='+str(nsig1)+' ' call += 'niter1='+str(niter1)+' ' call += 'ranges2='+str(ranges2)+' ' call += 'npoly2='+str(npoly2)+' ' call += 'nsig2='+str(nsig2)+' ' call += 'niter2='+str(niter2)+' ' popn = 'n' if (popnans): popn = 'y' call += 'popnans='+popn+ ' ' plotit = 'n' if (plot): 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) # start time kepmsg.clock('KEPDETREND started at',logfile,verbose) # test log file logfile = kepmsg.test(logfile) # clobber output file if clobber: status = kepio.clobber(outfile,logfile,verbose) if kepio.fileexists(outfile): message = 'ERROR -- KEPDETREND: ' + outfile + ' exists. Use clobber=yes' status = kepmsg.err(logfile,message,verbose) # open input file if status == 0: instr, status = kepio.openfits(infile,'readonly',logfile,verbose) tstart, tstop, bjdref, cadence, status = kepio.timekeys(instr,infile,logfile,verbose,status) # fudge non-compliant FITS keywords with no values if status == 0: instr = kepkey.emptykeys(instr,file,logfile,verbose) # read table structure if status == 0: table, status = kepio.readfitstab(infile,instr[1],logfile,verbose) # filter input data table if status == 0: work1 = numpy.array([table.field('time'), table.field(datacol), table.field(errcol)]) work1 = numpy.rot90(work1,3) work1 = work1[~numpy.isnan(work1).any(1)] # read table columns if status == 0: intime = work1[:,2] + bjdref indata = work1[:,1] inerr = work1[:,0] print(intime) # time ranges for region 1 (region to be corrected) if status == 0: time1 = []; data1 = []; err1 = [] t1start, t1stop, status = kepio.timeranges(ranges1,logfile,verbose) if status == 0: cadencelis1, status = kepstat.filterOnRange(intime,t1start,t1stop) if status == 0: for i in range(len(cadencelis1)): time1.append(intime[cadencelis1[i]]) data1.append(indata[cadencelis1[i]]) if errcol.lower() != 'none': err1.append(inerr[cadencelis1[i]]) t0 = time1[0] time1 = array(time1,dtype='float64') - t0 data1 = array(data1,dtype='float32') if errcol.lower() != 'none': err1 = array(err1,dtype='float32') else: err1 = None # fit function to range 1 if status == 0: functype = 'poly' + str(npoly1) pinit = [data1.mean()] if npoly1 > 0: for i in range(npoly1): pinit.append(0) pinit = array(pinit,dtype='float32') coeffs, errors, covar, iiter, sigma, chi2, dof, fit, plotx1, ploty1, status = \ kepfit.lsqclip(functype,pinit,time1,data1,err1,nsig1,nsig1,niter1, logfile,verbose) fit1 = indata * 0.0 for i in range(len(coeffs)): fit1 += coeffs[i] * (intime - t0)**i for i in range(len(intime)): if i not in cadencelis1: fit1[i] = 0.0 plotx1 += t0 print(coeffs) # time ranges for region 2 (region that is correct) if status == 0: time2 = []; data2 = []; err2 = [] t2start, t2stop, status = kepio.timeranges(ranges2,logfile,verbose) cadencelis2, status = kepstat.filterOnRange(intime,t2start,t2stop) for i in range(len(cadencelis2)): time2.append(intime[cadencelis2[i]]) data2.append(indata[cadencelis2[i]]) if errcol.lower() != 'none': err2.append(inerr[cadencelis2[i]]) t0 = time2[0] time2 = array(time2,dtype='float64') - t0 data2 = array(data2,dtype='float32') if errcol.lower() != 'none': err2 = array(err2,dtype='float32') else: err2 = None # fit function to range 2 if status == 0: functype = 'poly' + str(npoly2) pinit = [data2.mean()] if npoly2 > 0: for i in range(npoly2): pinit.append(0) pinit = array(pinit,dtype='float32') coeffs, errors, covar, iiter, sigma, chi2, dof, fit, plotx2, ploty2, status = \ kepfit.lsqclip(functype,pinit,time2,data2,err2,nsig2,nsig2,niter2, logfile,verbose) fit2 = indata * 0.0 for i in range(len(coeffs)): fit2 += coeffs[i] * (intime - t0)**i for i in range(len(intime)): if i not in cadencelis1: fit2[i] = 0.0 plotx2 += t0 # normalize data if status == 0: outdata = indata - fit1 + fit2 if errcol.lower() != 'none': outerr = inerr * 1.0 # comment keyword in output file if status == 0: status = kepkey.history(call,instr[0],outfile,logfile,verbose) # clean up x-axis unit if status == 0: intime0 = float(int(tstart / 100) * 100.0) if intime0 < 2.4e6: intime0 += 2.4e6 ptime = intime - intime0 plotx1 = plotx1 - intime0 plotx2 = plotx2 - intime0 xlab = 'BJD $-$ %d' % intime0 # clean up y-axis units if status == 0: pout = outdata ploty1 ploty2 nrm = len(str(int(numpy.nanmax(indata))))-1 indata = indata / 10**nrm pout = pout / 10**nrm ploty1 = ploty1 / 10**nrm ploty2 = ploty2 / 10**nrm ylab = '10$^%d$ e$^-$ s$^{-1}$' % nrm # data limits xmin = ptime.min() xmax = ptime.max() ymin = indata.min() ymax = indata.max() omin = pout.min() omax = pout.max() xr = xmax - xmin yr = ymax - ymin oo = omax - omin ptime = insert(ptime,[0],[ptime[0]]) ptime = append(ptime,[ptime[-1]]) indata = insert(indata,[0],[0.0]) indata = append(indata,[0.0]) pout = insert(pout,[0],[0.0]) pout = append(pout,0.0) # plot light curve if status == 0 and plot: try: params = {'backend': 'png', 'axes.linewidth': 2.5, 'axes.labelsize': labelsize, 'axes.font': 'sans-serif', 'axes.fontweight' : 'bold', 'text.fontsize': 12, 'legend.fontsize': 12, 'xtick.labelsize': ticksize, 'ytick.labelsize': ticksize} rcParams.update(params) except: pass pylab.figure(figsize=[xsize,ysize]) pylab.clf() # plot original data ax = pylab.axes([0.06,0.523,0.93,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)) # rotate y labels by 90 deg labels = ax.get_yticklabels() pylab.setp(labels, 'rotation', 90, fontsize=12) pylab.plot(ptime,indata,color=lcolor,linestyle='-',linewidth=lwidth) pylab.fill(ptime,indata,color=fcolor,linewidth=0.0,alpha=falpha) pylab.plot(plotx1,ploty1,color='r',linestyle='-',linewidth=2.0) pylab.plot(plotx2,ploty2,color='g',linestyle='-',linewidth=2.0) pylab.xlim(xmin-xr*0.01,xmax+xr*0.01) if ymin > 0.0: pylab.ylim(ymin-yr*0.01,ymax+yr*0.01) else: pylab.ylim(1.0e-10,ymax+yr*0.01) pylab.ylabel(ylab, {'color' : 'k'}) pylab.grid() # plot detrended data ax = pylab.axes([0.06,0.073,0.93,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)) # rotate y labels by 90 deg labels = ax.get_yticklabels() pylab.setp(labels, 'rotation', 90, fontsize=12) pylab.plot(ptime,pout,color=lcolor,linestyle='-',linewidth=lwidth) pylab.fill(ptime,pout,color=fcolor,linewidth=0.0,alpha=falpha) pylab.xlim(xmin-xr*0.01,xmax+xr*0.01) if ymin > 0.0: pylab.ylim(omin-oo*0.01,omax+oo*0.01) else: pylab.ylim(1.0e-10,omax+oo*0.01) pylab.xlabel(xlab, {'color' : 'k'}) try: pylab.ylabel(ylab, {'color' : 'k'}) except: ylab = '10**%d e-/s' % nrm pylab.ylabel(ylab, {'color' : 'k'}) # render plot if status == 0: if cmdLine: pylab.show() else: pylab.ion() pylab.plot([]) pylab.ioff() # write output file if status == 0 and popnans: instr[1].data.field(datacol)[good_data] = outdata instr[1].data.field(errcol)[good_data] = outerr instr[1].data.field(datacol)[bad_data] = None instr[1].data.field(errcol)[bad_data] = None instr.writeto(outfile) elif status == 0 and not popnans: for i in range(len(outdata)): instr[1].data.field(datacol)[i] = outdata[i] if errcol.lower() != 'none': instr[1].data.field(errcol)[i] = outerr[i] instr.writeto(outfile) # close input file if status == 0: status = kepio.closefits(instr,logfile,verbose) ## end time if (status == 0): message = 'KEPDETREND completed at' else: message = '\nKEPDETREND aborted at' kepmsg.clock(message,logfile,verbose)
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 kepflatten(infile,outfile,datacol,errcol,nsig,stepsize,winsize,npoly,niter,ranges, plot,clobber,verbose,logfile,status,cmdLine=False): # startup parameters status = 0 labelsize = 32 ticksize = 18 xsize = 16 ysize = 10 lcolor = '#0000ff' lwidth = 1.0 fcolor = '#ffff00' falpha = 0.2 # log the call hashline = '----------------------------------------------------------------------------' kepmsg.log(logfile,hashline,verbose) call = 'KEPFLATTEN -- ' call += 'infile='+infile+' ' call += 'outfile='+outfile+' ' call += 'datacol='+str(datacol)+' ' call += 'errcol='+str(errcol)+' ' call += 'nsig='+str(nsig)+' ' call += 'stepsize='+str(stepsize)+' ' call += 'winsize='+str(winsize)+' ' call += 'npoly='+str(npoly)+' ' call += 'niter='+str(niter)+' ' call += 'ranges='+str(ranges)+' ' plotit = 'n' if (plot): 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) # start time kepmsg.clock('KEPFLATTEN started at',logfile,verbose) # test log file logfile = kepmsg.test(logfile) # test winsize > stepsize if winsize < stepsize: message = 'ERROR -- KEPFLATTEN: winsize must be greater than stepsize' status = kepmsg.err(logfile,message,verbose) # clobber output file if clobber: status = kepio.clobber(outfile,logfile,verbose) if kepio.fileexists(outfile): message = 'ERROR -- KEPFLATTEN: ' + outfile + ' exists. Use clobber=yes' status = kepmsg.err(logfile,message,verbose) # open input file if status == 0: instr, status = kepio.openfits(infile,'readonly',logfile,verbose) if status == 0: tstart, tstop, bjdref, cadence, status = kepio.timekeys(instr,infile,logfile,verbose,status) if status == 0: try: work = instr[0].header['FILEVER'] cadenom = 1.0 except: cadenom = cadence # fudge non-compliant FITS keywords with no values if status == 0: instr = kepkey.emptykeys(instr,file,logfile,verbose) # read table structure if status == 0: table, status = kepio.readfitstab(infile,instr[1],logfile,verbose) # filter input data table if status == 0: try: datac = table.field(datacol) except: message = 'ERROR -- KEPFLATTEN: cannot find or read data column ' + datacol status = kepmsg.err(logfile,message,verbose) if status == 0: try: err = table.field(errcol) except: message = 'WARNING -- KEPFLATTEN: cannot find or read error column ' + errcol errcol = 'None' if status == 0: if errcol.lower() == 'none' or errcol == 'PSF_FLUX_ERR': err = datac * cadence err = numpy.sqrt(numpy.abs(err)) / cadence work1 = numpy.array([table.field('time'), datac, err]) else: work1 = numpy.array([table.field('time'), datac, err]) work1 = numpy.rot90(work1,3) work1 = work1[~numpy.isnan(work1).any(1)] # read table columns if status == 0: intime = work1[:,2] + bjdref indata = work1[:,1] inerr = work1[:,0] if len(intime) == 0: message = 'ERROR -- KEPFLATTEN: one of the input arrays is all NaN' status = kepmsg.err(logfile,message,verbose) # time ranges for region to be corrected if status == 0: t1, t2, status = kepio.timeranges(ranges,logfile,verbose) cadencelis, status = kepstat.filterOnRange(intime,t1,t2) # find limits of each time step if status == 0: tstep1 = []; tstep2 = [] work = intime[0] while work <= intime[-1]: tstep1.append(work) tstep2.append(array([work+winsize,intime[-1]],dtype='float64').min()) work += stepsize # find cadence limits of each time step if status == 0: cstep1 = []; cstep2 = [] for n in range(len(tstep1)): for i in range(len(intime)-1): if intime[i] <= tstep1[n] and intime[i+1] > tstep1[n]: for j in range(i,len(intime)-1): if intime[j] < tstep2[n] and intime[j+1] >= tstep2[n]: cstep1.append(i) cstep2.append(j+1) # comment keyword in output file if status == 0: status = kepkey.history(call,instr[0],outfile,logfile,verbose) # clean up x-axis unit if status == 0: intime0 = float(int(tstart / 100) * 100.0) ptime = intime - intime0 xlab = 'BJD $-$ %d' % intime0 # clean up y-axis units if status == 0: pout = copy(indata) nrm = len(str(int(pout.max())))-1 pout = pout / 10**nrm ylab = '10$^%d$ e$^-$ s$^{-1}$' % nrm # data limits xmin = ptime.min() xmax = ptime.max() ymin = pout.min() ymax = pout.max() xr = xmax - xmin yr = ymax - ymin ptime = insert(ptime,[0],[ptime[0]]) ptime = append(ptime,[ptime[-1]]) pout = insert(pout,[0],[0.0]) pout = append(pout,0.0) # plot light curve if status == 0 and plot: plotLatex = True try: params = {'backend': 'png', 'axes.linewidth': 2.5, 'axes.labelsize': labelsize, 'axes.font': 'sans-serif', 'axes.fontweight' : 'bold', 'text.fontsize': 12, 'legend.fontsize': 12, 'xtick.labelsize': ticksize, 'ytick.labelsize': ticksize} rcParams.update(params) except: plotLatex = False if status == 0 and plot: pylab.figure(figsize=[xsize,ysize]) pylab.clf() # plot data ax = pylab.axes([0.06,0.54,0.93,0.43]) # 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)) # rotate y labels by 90 deg labels = ax.get_yticklabels() pylab.setp(labels, 'rotation', 90) pylab.setp(pylab.gca(),xticklabels=[]) pylab.plot(ptime[1:-1],pout[1:-1],color=lcolor,linestyle='-',linewidth=lwidth) pylab.fill(ptime,pout,color=fcolor,linewidth=0.0,alpha=falpha) if not plotLatex: ylab = '10**%d electrons/sec' % nrm ylabel(ylab, {'color' : 'k'}) grid() # loop over each time step, fit data, determine rms if status == 0: fitarray = numpy.zeros((len(indata),len(cstep1)),dtype='float32') sigarray = numpy.zeros((len(indata),len(cstep1)),dtype='float32') fitarray[:,:] = numpy.nan sigarray[:,:] = numpy.nan masterfit = indata * 0.0 mastersigma = numpy.zeros(len(masterfit)) functype = 'poly' + str(npoly) for i in range(len(cstep1)): timeSeries = intime[cstep1[i]:cstep2[i]+1]-intime[cstep1[i]] dataSeries = indata[cstep1[i]:cstep2[i]+1] fitTimeSeries = numpy.array([],dtype='float32') fitDataSeries = numpy.array([],dtype='float32') pinit = [dataSeries.mean()] if npoly > 0: for j in range(npoly): pinit.append(0.0) pinit = array(pinit,dtype='float32') try: if len(fitarray[cstep1[i]:cstep2[i]+1,i]) > len(pinit): coeffs, errors, covar, iiter, sigma, chi2, dof, fit, plotx, ploty, status = \ kepfit.lsqclip(functype,pinit,timeSeries,dataSeries,None,nsig,nsig,niter, logfile,verbose) fitarray[cstep1[i]:cstep2[i]+1,i] = 0.0 sigarray[cstep1[i]:cstep2[i]+1,i] = sigma for j in range(len(coeffs)): fitarray[cstep1[i]:cstep2[i]+1,i] += coeffs[j] * timeSeries**j except: for j in range(cstep1[i],cstep2[i]+1): fitarray[cstep1[i]:cstep2[i]+1,i] = 0.0 sigarray[cstep1[i]:cstep2[i]+1,i] = 1.0e-10 message = 'WARNING -- KEPFLATTEN: could not fit range ' message += str(intime[cstep1[i]]) + '-' + str(intime[cstep2[i]]) kepmsg.warn(None,message) # find mean fit for each timestamp if status == 0: for i in range(len(indata)): masterfit[i] = scipy.stats.nanmean(fitarray[i,:]) mastersigma[i] = scipy.stats.nanmean(sigarray[i,:]) masterfit[-1] = masterfit[-4] #fudge masterfit[-2] = masterfit[-4] #fudge masterfit[-3] = masterfit[-4] #fudge pylab.plot(intime-intime0, masterfit / 10**nrm,'g',lw='3') # reject outliers if status == 0: rejtime = []; rejdata = []; naxis2 = 0 for i in range(len(masterfit)): if abs(indata[i] - masterfit[i]) > nsig * mastersigma[i] and i in cadencelis: rejtime.append(intime[i]) rejdata.append(indata[i]) rejtime = array(rejtime,dtype='float64') rejdata = array(rejdata,dtype='float32') if plot: pylab.plot(rejtime-intime0,rejdata / 10**nrm,'ro') # new data for output file if status == 0: outdata = indata / masterfit outerr = inerr / masterfit # plot ranges if status == 0 and plot: pylab.xlim(xmin-xr*0.01,xmax+xr*0.01) if ymin >= 0.0: pylab.ylim(ymin-yr*0.01,ymax+yr*0.01) else: pylab.ylim(1.0e-10,ymax+yr*0.01) # plot residual data if status == 0 and plot: ax = pylab.axes([0.06,0.09,0.93,0.43]) # force tick labels to be absolute rather than relative if status == 0 and plot: pylab.gca().xaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) pylab.gca().yaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False)) # rotate y labels by 90 deg labels = ax.get_yticklabels() setp(labels, 'rotation', 90) # clean up y-axis units if status == 0: pout = copy(outdata) ylab = 'Normalized Flux' # data limits if status == 0 and plot: ymin = pout.min() ymax = pout.max() yr = ymax - ymin pout = insert(pout,[0],[0.0]) pout = append(pout,0.0) pylab.plot(ptime[1:-1],pout[1:-1],color=lcolor,linestyle='-',linewidth=lwidth) pylab.fill(ptime,pout,color=fcolor,linewidth=0.0,alpha=falpha) pylab.xlabel(xlab, {'color' : 'k'}) pylab.ylabel(ylab, {'color' : 'k'}) pylab.grid() # plot ranges if status == 0 and plot: pylab.xlim(xmin-xr*0.01,xmax+xr*0.01) if ymin >= 0.0: pylab.ylim(ymin-yr*0.01,ymax+yr*0.01) else: pylab.ylim(1.0e-10,ymax+yr*0.01) # render plot if status == 0 and plot: pylab.savefig(re.sub('.fits','.png',outfile)) if cmdLine: pylab.show(block=True) else: pylab.ion() pylab.plot([]) pylab.ioff() # add NaNs back into data if status == 0: n = 0 work1 = array([],dtype='float32') work2 = array([],dtype='float32') instr, status = kepio.openfits(infile,'readonly',logfile,verbose) table, status = kepio.readfitstab(infile,instr[1],logfile,verbose) tn = table.field('time') dn = table.field(datacol) for i in range(len(table.field(0))): if numpy.isfinite(tn[i]) and numpy.isfinite(dn[i]) and numpy.isfinite(err[i]): try: work1 = numpy.append(work1,outdata[n]) work2 = numpy.append(work2,outerr[n]) n += 1 except: pass else: work1 = numpy.append(work1,numpy.nan) work2 = numpy.append(work2,numpy.nan) # history keyword in output file if status == 0: status = kepkey.history(call,instr[0],outfile,logfile,verbose) # write output file try: col1 = pyfits.Column(name='DETSAP_FLUX',format='E13.7',array=work1) col2 = pyfits.Column(name='DETSAP_FLUX_ERR',format='E13.7',array=work2) cols = instr[1].data.columns + col1 + col2 instr[1] = pyfits.new_table(cols,header=instr[1].header) instr.writeto(outfile) except ValueError: try: instr[1].data.field('DETSAP_FLUX')[:] = work1 instr[1].data.field('DETSAP_FLUX_ERR')[:] = work2 instr.writeto(outfile) except: message = 'ERROR -- KEPFLATTEN: cannot add DETSAP_FLUX data to FITS file' status = kepmsg.err(logfile,message,verbose) # close input file if status == 0: status = kepio.closefits(instr,logfile,verbose) ## end time if (status == 0): message = 'KEPFLATTEN completed at' else: message = '\nKEPFLATTEN aborted at' kepmsg.clock(message,logfile,verbose)