def clicker2(event): global mask, aid, bid, cid, did, eid, fid, done if event.inaxes: if event.button == 1: if (event.x > 601 and event.x < 801 and event.y > 422 and event.y < 482): disconnect(aid) disconnect(bid) disconnect(cid) disconnect(did) disconnect(eid) disconnect(fid) try: lines, status = kepio.openascii(maskfile, 'r', None, False) for line in lines: mask = [] work = line.strip().split('|') y0 = int(work[3]) x0 = int(work[4]) work = work[5].split(';') for i in range(len(work)): y = int(work[i].split(',')[0]) + y0 x = int(work[i].split(',')[1]) + x0 mask.append(str(x) + ',' + str(y)) pylab.clf() plotimage(cmdLine) except: txt = 'ERROR -- KEPMASK: Cannot open or read mask file ' + maskfile kepmsg.err(logfile, txt, True) return
def clicker2(event): global mask, aid, bid, cid, did, eid, fid, done if event.inaxes: if event.button == 1: if (event.x > 601 and event.x < 801 and event.y > 422 and event.y < 482): disconnect(aid) disconnect(bid) disconnect(cid) disconnect(did) disconnect(eid) disconnect(fid) try: lines, status = kepio.openascii(maskfile,'r',None,False) for line in lines: mask = [] work = line.strip().split('|') y0 = int(work[3]) x0 = int(work[4]) work = work[5].split(';') for i in range(len(work)): y = int(work[i].split(',')[0]) + y0 x = int(work[i].split(',')[1]) + x0 mask.append(str(x) + ',' + str(y)) pylab.clf() plotimage(cmdLine) except: txt = 'ERROR -- KEPMASK: Cannot open or read mask file ' + maskfile kepmsg.err(logfile,txt,True) return
def clicker1(event): global mask, aid, bid, cid, did, eid, fid, cmdLine if event.inaxes: if event.button == 1: if (event.x > 83 and event.x < 383 and event.y > 12 and event.y < 68): if kepio.fileexists(rinf): mask = [] lines, status = kepio.openascii(rinf,'r',logf,verb) for line in lines: line = line.strip().split(',') try: float(line[0]) float(line[1]) if barytime0 > 2.4e6: mask.append(float(line[0]) - barytime0) mask.append(float(line[1]) - barytime0) else: mask.append(float(line[0]) - barytime0 - 2.4e6) mask.append(float(line[1]) - barytime0 - 2.4e6) except: message = 'ERROR -- KEPRANGE: ascii format of ranges ' message += 'file not recognized.' status = kepmsg.err(logf,message,False) disconnect(aid) disconnect(bid) disconnect(cid) disconnect(did) disconnect(eid) disconnect(fid) plotlc(cmdLine) else: print 'WARNING -- KEPRANGE: input ranges file does not exist or was not provided' return
def kepffi(ffifile,kepid,ra,dec,aperfile,imin,imax,iscale,cmap,npix, verbose,logfile,status,cmdLine=False): global pimg, zscale, zmin, zmax, xmin, xmax, ymin, ymax, quarter global kepmag, skygroup, season, channel global module, output, row, column, maskfile, plotfile global pkepid, pkepmag, pra, pdec, colmap, mask # input arguments status = 0 seterr(all="ignore") maskfile = 'kepffi-' + str(kepid) + '.txt' plotfile = 'kepffi-' + str(kepid) + '.png' zmin = imin; zmax = imax; zscale = iscale; colmap = cmap # logg the call hashline = '----------------------------------------------------------------------------' kepmsg.log(logfile,hashline,verbose) call = 'KEPFFI -- ' call += 'ffifile='+ffifile+' ' call += 'kepid='+str(kepid)+' ' call += 'ra='+ra+' ' call += 'dec='+dec+' ' call += 'aperfile='+aperfile+' ' call += 'imin='+str(imin)+' ' call += 'imax='+str(imax)+' ' call += 'iscale='+str(iscale)+' ' call += 'cmap'+str(cmap)+' ' call += 'npix='+str(npix)+' ' chatter = 'n' if (verbose): chatter = 'y' call += 'verbose='+chatter+' ' call += 'logfile='+logfile kepmsg.log(logfile,call+'\n',verbose) # start time kepmsg.clock('KEPFFI started at',logfile,verbose) # reference color map if cmap == 'browse': status = cmap_plot(cmdLine) # open existing mask file if kepio.fileexists(aperfile): lines, status = kepio.openascii(aperfile,'r',logfile,verbose) for line in lines: line = line.strip().split('|') y0 = int(line[3]) x0 = int(line[4]) pixels = line[5].split(';') for pixel in pixels: m = y0 + int(pixel.split(',')[0]) n = x0 + int(pixel.split(',')[1]) mask.append(str(m)+','+str(n)) status = kepio.closeascii(lines,logfile,verbose) # RA and Dec conversion if kepid == 'None' or kepid == 'none' or kepid.strip() == '': try: mra = float(ra) mdec = float(dec) except: try: mra,mdec = sex2dec(ra,dec) except: txt = 'ERROR -- no sensible RA and Dec coordinates provided' sys.exit(txt) # open FFI FITS file if status == 0: ffi, status = openfits(ffifile,'readonly') try: quarter = ffi[0].header['QUARTER'] except: try: dateobs = ffi[0].header['DATE-OBS'] if dateobs == '2009-04-24': quarter = 0 if dateobs == '2009-04-25': quarter = 0 if dateobs == '2009-04-26': quarter = 0 if dateobs == '2009-06-19': quarter = 2 if dateobs == '2009-08-19': quarter = 2 if dateobs == '2009-09-17': quarter = 2 if dateobs == '2009-10-19': quarter = 3 if dateobs == '2009-11-18': quarter = 3 if dateobs == '2009-12-17': quarter = 3 except: txt = 'ERROR -- cannot determine quarter when FFI was taken. Either a\n' txt += 'QUARTER or DATE-OBS keyword is expected in the primary header' sys.exit(txt) if quarter == 0: quarter = 1 if quarter < 0: txt = 'ERROR -- cannot determine quarter from FFI. Try downloading a new\n' txt += 'version of KeplerFFI.py from http://keplergo.arc.nasa.gov' sys.exit() if int(quarter) == 0: season = 3 else: season = (int(quarter) - 2) % 4 # locate target in MAST try: int(kepid) kepid,ra,dec,kepmag,skygroup,channel,module,output,row,column \ = MASTKepID(kepid,season) pkepmag = kepmag; pkepid = kepid except: kepid,ra,dec,kepmag,skygroup,channel,module,output,row,column \ = MASTRADec(mra,mdec,8.0,season) ra,dec = dec2sex(ra,dec) pra = ra; pdec = dec print kepid,ra,dec,kepmag,skygroup,channel,module,output,row,column # read and close FFI FITS file img, status = readimage(ffi,int(channel)) status = closefits(ffi) # print target data 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 ' Column: %4s' % column print ' Row: %4s' % row print '' # subimage of channel for plot ymin = int(max([int(row)-npix/2,0])) ymax = int(min([int(row)+npix/2+1,img.shape[0]])) xmin = int(max([int(column)-npix/2,0])) xmax = int(min([int(column)+npix/2+1,img.shape[1]])) # intensity scale nstat = 2; pixels = [] for i in range(ymin,ymax+1): for j in range(xmin,xmax+1): pixels.append(img[i,j]) pixels = array(sort(pixels),dtype=float32) if int(float(len(pixels)) / 10 + 0.5) > nstat: nstat = int(float(len(pixels)) / 10 + 0.5) if not zmin: zmin = median(pixels[:nstat]) if not zmax: zmax = median(pixels[-nstat:]) if 'log' in zscale: img = log10(img) zmin = log10(zmin) zmax = log10(zmax) if ('sq' in zscale): img = sqrt(img) zmin = sqrt(zmin) zmax = sqrt(zmax) pimg = img[ymin:ymax,xmin:xmax] # plot limits ymin = float(ymin) - 0.5 ymax = float(ymax) - 0.5 xmin = float(xmin) - 0.5 xmax = float(xmax) - 0.5 # 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': 16, 'ytick.labelsize': 16} pylab.rcParams.update(params) except: pass if status == 0: pylab.figure(figsize=[10,7]) plotimage(cmdLine) # render plot if cmdLine: pylab.show() else: pylab.ion() pylab.plot([]) pylab.ioff() return
def keppca(infile, maskfile, outfile, components, plotpca, nreps, clobber, verbose, logfile, status, cmdLine=False): try: import mdp except: msg = 'ERROR -- KEPPCA: this task has an external python dependency to MDP, a Modular toolkit for Data Processing (http://mdp-toolkit.sourceforge.net). In order to take advantage of this PCA task, the user must first install MDP with their current python distribution. Note carefully that you may have more than python installation on your machine, and ensure that MDP is installed with the same version of python that the PyKE tools employ. Installation instructions for MDP can be found at the URL provided above.' status = kepmsg.err(None, msg, True) # startup parameters status = 0 labelsize = 32 ticksize = 18 xsize = 16 ysize = 10 lcolor = '#0000ff' lwidth = 1.0 fcolor = '#ffff00' falpha = 0.2 seterr(all="ignore") # log the call if status == 0: hashline = '----------------------------------------------------------------------------' kepmsg.log(logfile, hashline, verbose) call = 'KEPPCA -- ' call += 'infile=' + infile + ' ' call += 'maskfile=' + maskfile + ' ' call += 'outfile=' + outfile + ' ' call += 'components=' + components + ' ' ppca = 'n' if (plotpca): ppca = 'y' call += 'plotpca=' + ppca + ' ' call += 'nmaps=' + str(nreps) + ' ' 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 if status == 0: kepmsg.clock('KEPPCA started at', logfile, verbose) # test log file if status == 0: logfile = kepmsg.test(logfile) # clobber output file if status == 0: if clobber: status = kepio.clobber(outfile, logfile, verbose) if kepio.fileexists(outfile): message = 'ERROR -- KEPPCA: ' + outfile + ' exists. Use clobber=yes' status = kepmsg.err(logfile, message, verbose) # Set output file names - text file with data and plot if status == 0: dataout = copy(outfile) repname = re.sub('.fits', '.png', outfile) # open input file if status == 0: instr = pyfits.open(infile, mode='readonly', memmap=True) tstart, tstop, bjdref, cadence, status = kepio.timekeys( instr, infile, logfile, verbose, status) # open TPF FITS file if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, barytime, status = \ kepio.readTPF(infile,'TIME',logfile,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, flux_bkg, status = \ kepio.readTPF(infile,'FLUX_BKG',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, flux_bkg_err, status = \ kepio.readTPF(infile,'FLUX_BKG_ERR',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, qual, status = \ kepio.readTPF(infile,'QUALITY',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, pcorr1, status = \ kepio.readTPF(infile,'POS_CORR1',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, pcorr2, status = \ kepio.readTPF(infile,'POS_CORR2',logfile,verbose) # Save original data dimensions, in case of using maskfile if status == 0: xdimorig = xdim ydimorig = ydim # read mask definition file if it has been supplied if status == 0 and 'aper' not in maskfile.lower( ) and maskfile.lower() != 'all': maskx = array([], 'int') masky = array([], 'int') lines, status = kepio.openascii(maskfile, 'r', logfile, verbose) for line in lines: line = line.strip().split('|') if len(line) == 6: y0 = int(line[3]) x0 = int(line[4]) line = line[5].split(';') for items in line: try: masky = numpy.append(masky, y0 + int(items.split(',')[0])) maskx = numpy.append(maskx, x0 + int(items.split(',')[1])) except: continue status = kepio.closeascii(lines, logfile, verbose) if len(maskx) == 0 or len(masky) == 0: message = 'ERROR -- KEPPCA: ' + maskfile + ' contains no pixels.' status = kepmsg.err(logfile, message, verbose) xdim = max(maskx) - min(maskx) + 1 # Find largest x dimension of mask ydim = max(masky) - min(masky) + 1 # Find largest y dimension of mask # pad mask to ensure it is rectangular workx = array([], 'int') worky = array([], 'int') for ip in arange(min(maskx), max(maskx) + 1): for jp in arange(min(masky), max(masky) + 1): workx = append(workx, ip) worky = append(worky, jp) maskx = workx masky = worky # define new subimage bitmap... if status == 0 and maskfile.lower() != 'all': aperx = numpy.array([], 'int') apery = numpy.array([], 'int') aperb = maskx - x0 + xdimorig * ( masky - y0 ) # aperb is an array that contains the pixel numbers in the mask npix = len(aperb) # ...or use all pixels if status == 0 and maskfile.lower() == 'all': npix = xdimorig * ydimorig aperb = array([], 'int') aperb = numpy.r_[0:npix] # legal mask defined? if status == 0: if len(aperb) == 0: message = 'ERROR -- KEPPCA: no legal pixels within the subimage are defined.' status = kepmsg.err(logfile, message, verbose) # Identify principal components desired if status == 0: pcaout = [] txt = components.strip().split(',') for work1 in txt: try: pcaout.append(int(work1.strip())) except: work2 = work1.strip().split('-') try: for work3 in range(int(work2[0]), int(work2[1]) + 1): pcaout.append(work3) except: message = 'ERROR -- KEPPCA: cannot understand principal component list requested' status = kepmsg.err(logfile, message, verbose) if status == 0: pcaout = set(sort(pcaout)) pcarem = array( list(pcaout)) - 1 # The list of pca component numbers to be removed # Initialize arrays and variables, and apply pixel mask to the data if status == 0: ntim = 0 time = numpy.array([], dtype='float64') timecorr = numpy.array([], dtype='float32') cadenceno = numpy.array([], dtype='int') pixseries = numpy.array([], dtype='float32') errseries = numpy.array([], dtype='float32') bkgseries = numpy.array([], dtype='float32') berseries = numpy.array([], dtype='float32') quality = numpy.array([], dtype='float32') pos_corr1 = numpy.array([], dtype='float32') pos_corr2 = numpy.array([], dtype='float32') nrows = numpy.size(fluxpixels, 0) # Apply the pixel mask so we are left with only the desired pixels if status == 0: pixseriesb = fluxpixels[:, aperb] errseriesb = errpixels[:, aperb] bkgseriesb = flux_bkg[:, aperb] berseriesb = flux_bkg_err[:, aperb] # Read in the data to various arrays if status == 0: for i in range(nrows): if qual[i] < 10000 and \ numpy.isfinite(barytime[i]) and \ numpy.isfinite(fluxpixels[i,int(ydim*xdim/2+0.5)]) and \ numpy.isfinite(fluxpixels[i,1+int(ydim*xdim/2+0.5)]): ntim += 1 time = numpy.append(time, barytime[i]) timecorr = numpy.append(timecorr, tcorr[i]) cadenceno = numpy.append(cadenceno, cadno[i]) pixseries = numpy.append(pixseries, pixseriesb[i]) errseries = numpy.append(errseries, errseriesb[i]) bkgseries = numpy.append(bkgseries, bkgseriesb[i]) berseries = numpy.append(berseries, berseriesb[i]) quality = numpy.append(quality, qual[i]) pos_corr1 = numpy.append(pos_corr1, pcorr1[i]) pos_corr2 = numpy.append(pos_corr2, pcorr2[i]) pixseries = numpy.reshape(pixseries, (ntim, npix)) errseries = numpy.reshape(errseries, (ntim, npix)) bkgseries = numpy.reshape(bkgseries, (ntim, npix)) berseries = numpy.reshape(berseries, (ntim, npix)) tmp = numpy.median(pixseries, axis=1) for i in range(len(tmp)): pixseries[i] = pixseries[i] - tmp[i] # Figure out which pixels are undefined/nan and remove them. Keep track for adding back in later if status == 0: nanpixels = numpy.array([], dtype='int') i = 0 while (i < npix): if numpy.isnan(pixseries[0, i]): nanpixels = numpy.append(nanpixels, i) npix = npix - 1 i = i + 1 pixseries = numpy.delete(pixseries, nanpixels, 1) errseries = numpy.delete(errseries, nanpixels, 1) pixseries[numpy.isnan(pixseries)] = random.gauss(100, 10) errseries[numpy.isnan(errseries)] = 10 # Compute statistical weights, means, standard deviations if status == 0: weightseries = (pixseries / errseries)**2 pixMean = numpy.average(pixseries, axis=0, weights=weightseries) pixStd = numpy.std(pixseries, axis=0) # Normalize the input by subtracting the mean and divising by the standard deviation. # This makes it a correlation-based PCA, which is what we want. if status == 0: pixseriesnorm = (pixseries - pixMean) / pixStd # Number of principal components to compute. Setting it equal to the number of pixels if status == 0: nvecin = npix # Run PCA using the MDP Whitening PCA, which produces normalized PCA components (zero mean and unit variance) if status == 0: pcan = mdp.nodes.WhiteningNode(svd=True) pcar = pcan.execute(pixseriesnorm) eigvec = pcan.get_recmatrix() model = pcar # Re-insert nan columns as zeros if status == 0: for i in range(0, len(nanpixels)): nanpixels[i] = nanpixels[i] - i eigvec = numpy.insert(eigvec, nanpixels, 0, 1) pixMean = numpy.insert(pixMean, nanpixels, 0, 0) # Make output eigenvectors (correlation images) into xpix by ypix images if status == 0: eigvec = eigvec.reshape(nvecin, ydim, xdim) # Calculate sum of all pixels to display as raw lightcurve and other quantities if status == 0: pixseriessum = sum(pixseries, axis=1) nrem = len(pcarem) # Number of components to remove nplot = npix # Number of pcas to plot - currently set to plot all components, but could set # nplot = nrem to just plot as many components as is being removed # Subtract components by fitting them to the summed light curve if status == 0: x0 = numpy.tile(-1.0, 1) for k in range(0, nrem): def f(x): fluxcor = pixseriessum for k in range(0, len(x)): fluxcor = fluxcor - x[k] * model[:, pcarem[k]] return mad(fluxcor) if k == 0: x0 = array([-1.0]) else: x0 = numpy.append(x0, 1.0) myfit = scipy.optimize.fmin(f, x0, maxiter=50000, maxfun=50000, disp=False) x0 = myfit # Now that coefficients for all components have been found, subtract them to produce a calibrated time-series, # and then divide by the robust mean to produce a normalized time series as well if status == 0: c = myfit fluxcor = pixseriessum for k in range(0, nrem): fluxcor = fluxcor - c[k] * model[:, pcarem[k]] normfluxcor = fluxcor / mean(reject_outliers(fluxcor, 2)) # input file data if status == 0: cards0 = instr[0].header.cards cards1 = instr[1].header.cards cards2 = instr[2].header.cards table = instr[1].data[:] maskmap = copy(instr[2].data) # subimage physical WCS data if status == 0: crpix1p = cards2['CRPIX1P'].value crpix2p = cards2['CRPIX2P'].value crval1p = cards2['CRVAL1P'].value crval2p = cards2['CRVAL2P'].value cdelt1p = cards2['CDELT1P'].value cdelt2p = cards2['CDELT2P'].value # dummy columns for output file if status == 0: sap_flux_err = numpy.empty(len(time)) sap_flux_err[:] = numpy.nan sap_bkg = numpy.empty(len(time)) sap_bkg[:] = numpy.nan sap_bkg_err = numpy.empty(len(time)) sap_bkg_err[:] = numpy.nan pdc_flux = numpy.empty(len(time)) pdc_flux[:] = numpy.nan pdc_flux_err = numpy.empty(len(time)) pdc_flux_err[:] = numpy.nan psf_centr1 = numpy.empty(len(time)) psf_centr1[:] = numpy.nan psf_centr1_err = numpy.empty(len(time)) psf_centr1_err[:] = numpy.nan psf_centr2 = numpy.empty(len(time)) psf_centr2[:] = numpy.nan psf_centr2_err = numpy.empty(len(time)) psf_centr2_err[:] = numpy.nan mom_centr1 = numpy.empty(len(time)) mom_centr1[:] = numpy.nan mom_centr1_err = numpy.empty(len(time)) mom_centr1_err[:] = numpy.nan mom_centr2 = numpy.empty(len(time)) mom_centr2[:] = numpy.nan mom_centr2_err = numpy.empty(len(time)) mom_centr2_err[:] = numpy.nan # mask bitmap if status == 0 and 'aper' not in maskfile.lower( ) and maskfile.lower() != 'all': for i in range(maskmap.shape[0]): for j in range(maskmap.shape[1]): aperx = append(aperx, crval1p + (j + 1 - crpix1p) * cdelt1p) apery = append(apery, crval2p + (i + 1 - crpix2p) * cdelt2p) if maskmap[i, j] == 0: pass else: maskmap[i, j] = 1 for k in range(len(maskx)): if aperx[-1] == maskx[k] and apery[-1] == masky[k]: maskmap[i, j] = 3 # construct output primary extension if status == 0: hdu0 = pyfits.PrimaryHDU() for i in range(len(cards0)): if cards0[i].keyword not in list(hdu0.header.keys()): hdu0.header[cards0[i].keyword] = (cards0[i].value, cards0[i].comment) else: hdu0.header.cards[ cards0[i].keyword].comment = cards0[i].comment status = kepkey.history(call, hdu0, outfile, logfile, verbose) outstr = HDUList(hdu0) # construct output light curve extension if status == 0: col1 = Column(name='TIME', format='D', unit='BJD - 2454833', array=time) col2 = Column(name='TIMECORR', format='E', unit='d', array=timecorr) col3 = Column(name='CADENCENO', format='J', array=cadenceno) col4 = Column(name='SAP_FLUX', format='E', unit='e-/s', array=pixseriessum) col5 = Column(name='SAP_FLUX_ERR', format='E', unit='e-/s', array=sap_flux_err) col6 = Column(name='SAP_BKG', format='E', unit='e-/s', array=sap_bkg) col7 = Column(name='SAP_BKG_ERR', format='E', unit='e-/s', array=sap_bkg_err) col8 = Column(name='PDCSAP_FLUX', format='E', unit='e-/s', array=pdc_flux) col9 = Column(name='PDCSAP_FLUX_ERR', format='E', unit='e-/s', array=pdc_flux_err) col10 = Column(name='SAP_QUALITY', format='J', array=quality) col11 = Column(name='PSF_CENTR1', format='E', unit='pixel', array=psf_centr1) col12 = Column(name='PSF_CENTR1_ERR', format='E', unit='pixel', array=psf_centr1_err) col13 = Column(name='PSF_CENTR2', format='E', unit='pixel', array=psf_centr2) col14 = Column(name='PSF_CENTR2_ERR', format='E', unit='pixel', array=psf_centr2_err) col15 = Column(name='MOM_CENTR1', format='E', unit='pixel', array=mom_centr1) col16 = Column(name='MOM_CENTR1_ERR', format='E', unit='pixel', array=mom_centr1_err) col17 = Column(name='MOM_CENTR2', format='E', unit='pixel', array=mom_centr2) col18 = Column(name='MOM_CENTR2_ERR', format='E', unit='pixel', array=mom_centr2_err) col19 = Column(name='POS_CORR1', format='E', unit='pixel', array=pos_corr1) col20 = Column(name='POS_CORR2', format='E', unit='pixel', array=pos_corr2) col21 = Column(name='PCA_FLUX', format='E', unit='e-/s', array=fluxcor) col22 = Column(name='PCA_FLUX_NRM', format='E', array=normfluxcor) cols = ColDefs([col1,col2,col3,col4,col5,col6,col7,col8,col9,col10,col11, \ col12,col13,col14,col15,col16,col17,col18,col19,col20,col21,col22]) hdu1 = new_table(cols) hdu1.header['TTYPE1'] = ('TIME', 'column title: data time stamps') hdu1.header['TFORM1'] = ('D', 'data type: float64') hdu1.header['TUNIT1'] = ('BJD - 2454833', 'column units: barycenter corrected JD') hdu1.header['TDISP1'] = ('D12.7', 'column display format') hdu1.header['TTYPE2'] = ( 'TIMECORR', 'column title: barycentric-timeslice correction') hdu1.header['TFORM2'] = ('E', 'data type: float32') hdu1.header['TUNIT2'] = ('d', 'column units: days') hdu1.header['TTYPE3'] = ('CADENCENO', 'column title: unique cadence number') hdu1.header['TFORM3'] = ('J', 'column format: signed integer32') hdu1.header['TTYPE4'] = ('SAP_FLUX', 'column title: aperture photometry flux') hdu1.header['TFORM4'] = ('E', 'column format: float32') hdu1.header['TUNIT4'] = ('e-/s', 'column units: electrons per second') hdu1.header['TTYPE5'] = ('SAP_FLUX_ERR', 'column title: aperture phot. flux error') hdu1.header['TFORM5'] = ('E', 'column format: float32') hdu1.header['TUNIT5'] = ( 'e-/s', 'column units: electrons per second (1-sigma)') hdu1.header['TTYPE6'] = ( 'SAP_BKG', 'column title: aperture phot. background flux') hdu1.header['TFORM6'] = ('E', 'column format: float32') hdu1.header['TUNIT6'] = ('e-/s', 'column units: electrons per second') hdu1.header['TTYPE7'] = ( 'SAP_BKG_ERR', 'column title: ap. phot. background flux error') hdu1.header['TFORM7'] = ('E', 'column format: float32') hdu1.header['TUNIT7'] = ( 'e-/s', 'column units: electrons per second (1-sigma)') hdu1.header['TTYPE8'] = ('PDCSAP_FLUX', 'column title: PDC photometry flux') hdu1.header['TFORM8'] = ('E', 'column format: float32') hdu1.header['TUNIT8'] = ('e-/s', 'column units: electrons per second') hdu1.header['TTYPE9'] = ('PDCSAP_FLUX_ERR', 'column title: PDC flux error') hdu1.header['TFORM9'] = ('E', 'column format: float32') hdu1.header['TUNIT9'] = ( 'e-/s', 'column units: electrons per second (1-sigma)') hdu1.header['TTYPE10'] = ( 'SAP_QUALITY', 'column title: aperture photometry quality flag') hdu1.header['TFORM10'] = ('J', 'column format: signed integer32') hdu1.header['TTYPE11'] = ('PSF_CENTR1', 'column title: PSF fitted column centroid') hdu1.header['TFORM11'] = ('E', 'column format: float32') hdu1.header['TUNIT11'] = ('pixel', 'column units: pixel') hdu1.header['TTYPE12'] = ('PSF_CENTR1_ERR', 'column title: PSF fitted column error') hdu1.header['TFORM12'] = ('E', 'column format: float32') hdu1.header['TUNIT12'] = ('pixel', 'column units: pixel') hdu1.header['TTYPE13'] = ('PSF_CENTR2', 'column title: PSF fitted row centroid') hdu1.header['TFORM13'] = ('E', 'column format: float32') hdu1.header['TUNIT13'] = ('pixel', 'column units: pixel') hdu1.header['TTYPE14'] = ('PSF_CENTR2_ERR', 'column title: PSF fitted row error') hdu1.header['TFORM14'] = ('E', 'column format: float32') hdu1.header['TUNIT14'] = ('pixel', 'column units: pixel') hdu1.header['TTYPE15'] = ( 'MOM_CENTR1', 'column title: moment-derived column centroid') hdu1.header['TFORM15'] = ('E', 'column format: float32') hdu1.header['TUNIT15'] = ('pixel', 'column units: pixel') hdu1.header['TTYPE16'] = ('MOM_CENTR1_ERR', 'column title: moment-derived column error') hdu1.header['TFORM16'] = ('E', 'column format: float32') hdu1.header['TUNIT16'] = ('pixel', 'column units: pixel') hdu1.header['TTYPE17'] = ('MOM_CENTR2', 'column title: moment-derived row centroid') hdu1.header['TFORM17'] = ('E', 'column format: float32') hdu1.header['TUNIT17'] = ('pixel', 'column units: pixel') hdu1.header['TTYPE18'] = ('MOM_CENTR2_ERR', 'column title: moment-derived row error') hdu1.header['TFORM18'] = ('E', 'column format: float32') hdu1.header['TUNIT18'] = ('pixel', 'column units: pixel') hdu1.header['TTYPE19'] = ( 'POS_CORR1', 'column title: col correction for vel. abbern') hdu1.header['TFORM19'] = ('E', 'column format: float32') hdu1.header['TUNIT19'] = ('pixel', 'column units: pixel') hdu1.header['TTYPE20'] = ( 'POS_CORR2', 'column title: row correction for vel. abbern') hdu1.header['TFORM20'] = ('E', 'column format: float32') hdu1.header['TUNIT20'] = ('pixel', 'column units: pixel') hdu1.header['TTYPE21'] = ('PCA_FLUX', 'column title: PCA-corrected flux') hdu1.header['TFORM21'] = ('E', 'column format: float32') hdu1.header['TUNIT21'] = ('pixel', 'column units: e-/s') hdu1.header['TTYPE22'] = ( 'PCA_FLUX_NRM', 'column title: normalized PCA-corrected flux') hdu1.header['TFORM22'] = ('E', 'column format: float32') hdu1.header['EXTNAME'] = ('LIGHTCURVE', 'name of extension') for i in range(len(cards1)): if (cards1[i].keyword not in list(hdu1.header.keys()) and cards1[i].keyword[: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[cards1[i].keyword] = (cards1[i].value, cards1[i].comment) outstr.append(hdu1) # construct output mask bitmap extension if status == 0: hdu2 = ImageHDU(maskmap) for i in range(len(cards2)): if cards2[i].keyword not in list(hdu2.header.keys()): hdu2.header[cards2[i].keyword] = (cards2[i].value, cards2[i].comment) else: hdu2.header.cards[ cards2[i].keyword].comment = cards2[i].comment outstr.append(hdu2) # construct principal component table if status == 0: cols = [ Column(name='TIME', format='E', unit='BJD - 2454833', array=time) ] for i in range(len(pcar[0, :])): colname = 'PC' + str(i + 1) col = Column(name=colname, format='E', array=pcar[:, i]) cols.append(col) hdu3 = new_table(ColDefs(cols)) hdu3.header['EXTNAME'] = ('PRINCIPAL_COMPONENTS', 'name of extension') hdu3.header['TTYPE1'] = ('TIME', 'column title: data time stamps') hdu3.header['TFORM1'] = ('D', 'data type: float64') hdu3.header['TUNIT1'] = ('BJD - 2454833', 'column units: barycenter corrected JD') hdu3.header['TDISP1'] = ('D12.7', 'column display format') for i in range(len(pcar[0, :])): hdu3.header['TTYPE' + str(i + 2)] = \ ('PC' + str(i + 1), 'column title: principal component number' + str(i + 1)) hdu3.header['TFORM' + str(i + 2)] = ('E', 'column format: float32') outstr.append(hdu3) # write output file if status == 0: outstr.writeto(outfile) # close input structure if status == 0: status = kepio.closefits(instr, logfile, verbose) # Create PCA report if status == 0 and plotpca: npp = 7 # Number of plots per page l = 1 repcnt = 1 for k in range(nreps): # First plot of every pagewith flux image, flux and calibrated time series status = kepplot.define(16, 12, logfile, verbose) if (k % (npp - 1) == 0): pylab.figure(figsize=[10, 16]) subplot2grid((npp, 6), (0, 0), colspan=2) # imshow(log10(pixMean.reshape(xdim,ydim).T-min(pixMean)+1),interpolation="nearest",cmap='RdYlBu') imshow(log10( flipud(pixMean.reshape(ydim, xdim)) - min(pixMean) + 1), interpolation="nearest", cmap='RdYlBu') xticks([]) yticks([]) ax1 = subplot2grid((npp, 6), (0, 2), colspan=4) px = copy(time) + bjdref py = copy(pixseriessum) px, xlab, status = kepplot.cleanx(px, logfile, verbose) py, ylab, status = kepplot.cleany(py, 1.0, logfile, verbose) kepplot.RangeOfPlot(px, py, 0.01, False) kepplot.plot1d(px, py, cadence, lcolor, lwidth, fcolor, falpha, True) py = copy(fluxcor) py, ylab, status = kepplot.cleany(py, 1.0, logfile, verbose) plot(px, py, marker='.', color='r', linestyle='', markersize=1.0) kepplot.labels('', re.sub('\)', '', re.sub('Flux \(', '', ylab)), 'k', 18) grid() setp(ax1.get_xticklabels(), visible=False) # plot principal components subplot2grid((npp, 6), (l, 0), colspan=2) imshow(eigvec[k], interpolation="nearest", cmap='RdYlBu') xlim(-0.5, xdim - 0.5) ylim(-0.5, ydim - 0.5) xticks([]) yticks([]) # The last plot on the page that should have the xlabel if (k % (npp - 1) == npp - 2 or k == nvecin - 1): subplot2grid((npp, 6), (l, 2), colspan=4) py = copy(model[:, k]) kepplot.RangeOfPlot(px, py, 0.01, False) kepplot.plot1d(px, py, cadence, 'r', lwidth, 'g', falpha, True) kepplot.labels(xlab, 'PC ' + str(k + 1), 'k', 18) pylab.grid() pylab.tight_layout() l = 1 pylab.savefig(re.sub('.png', '_%d.png' % repcnt, repname)) if not cmdLine: kepplot.render(cmdLine) repcnt += 1 # The other plots on the page that should have no xlabel else: ax2 = subplot2grid((npp, 6), (l, 2), colspan=4) py = copy(model[:, k]) kepplot.RangeOfPlot(px, py, 0.01, False) kepplot.plot1d(px, py, cadence, 'r', lwidth, 'g', falpha, True) kepplot.labels('', 'PC ' + str(k + 1), 'k', 18) grid() setp(ax2.get_xticklabels(), visible=False) pylab.tight_layout() l = l + 1 pylab.savefig(re.sub('.png', '_%d.png' % repcnt, repname)) if not cmdLine: kepplot.render(cmdLine) # plot style and size if status == 0 and plotpca: status = kepplot.define(labelsize, ticksize, logfile, verbose) pylab.figure(figsize=[xsize, ysize]) pylab.clf() # plot aperture photometry and PCA corrected data if status == 0 and plotpca: ax = kepplot.location([0.06, 0.54, 0.93, 0.43]) px = copy(time) + bjdref py = copy(pixseriessum) px, xlab, status = kepplot.cleanx(px, logfile, verbose) py, ylab, status = kepplot.cleany(py, 1.0, logfile, verbose) kepplot.RangeOfPlot(px, py, 0.01, False) kepplot.plot1d(px, py, cadence, lcolor, lwidth, fcolor, falpha, True) py = copy(fluxcor) py, ylab, status = kepplot.cleany(py, 1.0, logfile, verbose) kepplot.plot1d(px, py, cadence, 'r', 2, fcolor, 0.0, True) pylab.setp(pylab.gca(), xticklabels=[]) kepplot.labels('', ylab, 'k', 24) pylab.grid() # plot aperture photometry and PCA corrected data if status == 0 and plotpca: ax = kepplot.location([0.06, 0.09, 0.93, 0.43]) yr = array([], 'float32') npc = min([6, nrem]) for i in range(npc - 1, -1, -1): py = pcar[:, i] * c[i] py, ylab, status = kepplot.cleany(py, 1.0, logfile, verbose) cl = float(i) / (float(npc)) kepplot.plot1d(px, py, cadence, [1.0 - cl, 0.0, cl], 2, fcolor, 0.0, True) yr = append(yr, py) y1 = max(yr) y2 = -min(yr) kepplot.RangeOfPlot(px, array([-y1, y1, -y2, y2]), 0.01, False) kepplot.labels(xlab, 'Principal Components', 'k', 24) pylab.grid() # save plot to file if status == 0 and plotpca: pylab.savefig(repname) # render plot if status == 0 and plotpca: kepplot.render(cmdLine) # stop time if status == 0: kepmsg.clock('KEPPCA ended at', logfile, verbose) return
def keppca(infile,maskfile,outfile,components,clobber,verbose,logfile,status): # startup parameters cmdLine=False status = 0 labelsize = 32 ticksize = 18 xsize = 16 ysize = 10 lcolor = '#0000ff' lwidth = 1.0 fcolor = '#ffff00' falpha = 0.2 seterr(all="ignore") # log the call hashline = '----------------------------------------------------------------------------' kepmsg.log(logfile,hashline,verbose) call = 'KEPPCA -- ' call += 'infile='+infile+' ' call += 'maskfile='+maskfile+' ' call += 'outfile='+outfile+' ' call += 'components='+components+' ' 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('KEPPCA 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 -- KEPPCA: ' + outfile + ' exists. Use --clobber' status = kepmsg.err(logfile,message,verbose) # open input file status = 0 instr = pyfits.open(infile,mode='readonly',memmap=True) if status == 0: 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) # input file data if status == 0: cards0 = instr[0].header.ascardlist() cards1 = instr[1].header.ascardlist() cards2 = instr[2].header.ascardlist() table = instr[1].data[:] maskmap = copy(instr[2].data) # open TPF FITS file if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, barytime, status = \ kepio.readTPF(infile,'TIME',logfile,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, flux_bkg, status = \ kepio.readTPF(infile,'FLUX_BKG',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, flux_bkg_err, status = \ kepio.readTPF(infile,'FLUX_BKG_ERR',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, qual, status = \ kepio.readTPF(infile,'QUALITY',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, pcorr1, status = \ kepio.readTPF(infile,'POS_CORR1',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, pcorr2, status = \ kepio.readTPF(infile,'POS_CORR2',logfile,verbose) # read mask definition file if status == 0 and 'aper' not in maskfile.lower() and maskfile.lower() != 'all': maskx = array([],'int') masky = array([],'int') lines, status = kepio.openascii(maskfile,'r',logfile,verbose) for line in lines: line = line.strip().split('|') if len(line) == 6: y0 = int(line[3]) x0 = int(line[4]) line = line[5].split(';') for items in line: try: masky = numpy.append(masky,y0 + int(items.split(',')[0])) maskx = numpy.append(maskx,x0 + int(items.split(',')[1])) except: continue status = kepio.closeascii(lines,logfile,verbose) if len(maskx) == 0 or len(masky) == 0: message = 'ERROR -- KEPPCA: ' + maskfile + ' contains no pixels.' status = kepmsg.err(logfile,message,verbose) # subimage physical WCS data if status == 0: crpix1p = cards2['CRPIX1P'].value crpix2p = cards2['CRPIX2P'].value crval1p = cards2['CRVAL1P'].value crval2p = cards2['CRVAL2P'].value cdelt1p = cards2['CDELT1P'].value cdelt2p = cards2['CDELT2P'].value # define new subimage bitmap... if status == 0 and 'aper' not in maskfile.lower() and maskfile.lower() != 'all': aperx = numpy.array([],'int') apery = numpy.array([],'int') aperb = numpy.array([],'int') for i in range(maskmap.shape[0]): for j in range(maskmap.shape[1]): aperx = numpy.append(aperx,crval1p + (j + 1 - crpix1p) * cdelt1p) apery = numpy.append(apery,crval2p + (i + 1 - crpix2p) * cdelt2p) if maskmap[i,j] == 0: aperb = numpy.append(aperb,0) else: aperb = numpy.append(aperb,1) maskmap[i,j] = 1 for k in range(len(maskx)): if aperx[-1] == maskx[k] and apery[-1] == masky[k]: aperb[-1] = 3 maskmap[i,j] = 3 # ...or use old subimage bitmap if status == 0 and 'aper' in maskfile.lower(): aperb = array([],'int') for i in range(maskmap.shape[0]): for j in range(maskmap.shape[1]): aperb = numpy.append(aperb,maskmap[i,j]) # ...or use all pixels if status == 0 and maskfile.lower() == 'all': aperb = array([],'int') for i in range(maskmap.shape[0]): for j in range(maskmap.shape[1]): if maskmap[i,j] == 0: aperb = numpy.append(aperb,0) else: aperb = numpy.append(aperb,3) maskmap[i,j] = 3 # legal mask defined? if status == 0: if len(aperb) == 0: message = 'ERROR -- KEPPCA: no legal pixels within the subimage are defined.' status = kepmsg.err(logfile,message,verbose) # identify principal components to be combined if status == 0: pcaout = [] txt = components.strip().split(',') for work1 in txt: try: pcaout.append(int(work1.strip())) except: work2 = work1.strip().split('-') try: for work3 in range(int(work2[0]),int(work2[1]) + 1): pcaout.append(work3) except: message = 'ERROR -- KEPPCA: cannot understand principal component list requested' status = kepmsg.err(logfile,message,verbose) if status == 0: pcaout = set(sort(pcaout)) # flux pixel array size if status == 0: ntim = 0 time = numpy.array([],dtype='float64') timecorr = numpy.array([],dtype='float32') cadenceno = numpy.array([],dtype='int') pixseries = numpy.array([],dtype='float32') errseries = numpy.array([],dtype='float32') bkgseries = numpy.array([],dtype='float32') berseries = numpy.array([],dtype='float32') quality = numpy.array([],dtype='float32') pos_corr1 = numpy.array([],dtype='float32') pos_corr2 = numpy.array([],dtype='float32') nrows = numpy.size(fluxpixels,0) npix = numpy.size(fluxpixels,1) # remove NaN timestamps for i in range(nrows): if qual[i] == 0 and \ numpy.isfinite(barytime[i]) and \ numpy.isfinite(fluxpixels[i,ydim*xdim/2]) and \ numpy.isfinite(fluxpixels[i,1+ydim*xdim/2]): ntim += 1 time = numpy.append(time,barytime[i]) timecorr = numpy.append(timecorr,tcorr[i]) cadenceno = numpy.append(cadenceno,cadno[i]) pixseries = numpy.append(pixseries,fluxpixels[i]) errseries = numpy.append(errseries,errpixels[i]) bkgseries = numpy.append(bkgseries,flux_bkg[i]) berseries = numpy.append(berseries,flux_bkg_err[i]) quality = numpy.append(quality,qual[i]) pos_corr1 = numpy.append(pos_corr1,pcorr1[i]) pos_corr2 = numpy.append(pos_corr2,pcorr2[i]) pixseries = numpy.reshape(pixseries,(-1,npix)) errseries = numpy.reshape(errseries,(-1,npix)) bkgseries = numpy.reshape(bkgseries,(-1,npix)) berseries = numpy.reshape(berseries,(-1,npix)) # dummy columns for output file if status == 0: pdc_flux = numpy.empty(len(time)); pdc_flux[:] = numpy.nan pdc_flux_err = numpy.empty(len(time)); pdc_flux_err[:] = numpy.nan psf_centr1 = numpy.empty(len(time)); psf_centr1[:] = numpy.nan psf_centr1_err = numpy.empty(len(time)); psf_centr1_err[:] = numpy.nan psf_centr2 = numpy.empty(len(time)); psf_centr2[:] = numpy.nan psf_centr2_err = numpy.empty(len(time)); psf_centr2_err[:] = numpy.nan mom_centr1 = numpy.empty(len(time)); mom_centr1[:] = numpy.nan mom_centr1_err = numpy.empty(len(time)); mom_centr1_err[:] = numpy.nan mom_centr2 = numpy.empty(len(time)); mom_centr2[:] = numpy.nan mom_centr2_err = numpy.empty(len(time)); mom_centr2_err[:] = numpy.nan # subtract mean over time from each pixel in the mask if status == 0: nmask = 0 for i in range(npix): if aperb[i] == 3: nmask += 1 work1 = numpy.zeros((len(pixseries),nmask)) nmask = -1 for i in range(npix): if aperb[i] == 3: nmask += 1 maskedFlux = numpy.ma.masked_invalid(pixseries[:,i]) pixMean = numpy.mean(maskedFlux) if numpy.isfinite(pixMean): work1[:,nmask] = maskedFlux - pixMean else: work1[:,nmask] = numpy.zeros((ntim)) # calculate covariance matrix if status == 0: work2 = work1.T covariance = numpy.cov(work2) # determine eigenfunctions and eigenvectors of the covariance matrix if status == 0: [latent,coeff] = numpy.linalg.eig(covariance) # projection of the data in the new space if status == 0: score = numpy.dot(coeff.T,work2).T # construct new table data if status == 0: sap_flux = numpy.array([],'float32') sap_flux_err = numpy.array([],'float32') sap_bkg = numpy.array([],'float32') sap_bkg_err = numpy.array([],'float32') for i in range(len(time)): work1 = numpy.array([],'float64') work2 = numpy.array([],'float64') work3 = numpy.array([],'float64') work4 = numpy.array([],'float64') work5 = numpy.array([],'float64') for j in range(len(aperb)): if (aperb[j] == 3): work1 = numpy.append(work1,pixseries[i,j]) work2 = numpy.append(work2,errseries[i,j]) work3 = numpy.append(work3,bkgseries[i,j]) work4 = numpy.append(work4,berseries[i,j]) sap_flux = numpy.append(sap_flux,kepstat.sum(work1)) sap_flux_err = numpy.append(sap_flux_err,kepstat.sumerr(work2)) sap_bkg = numpy.append(sap_bkg,kepstat.sum(work3)) sap_bkg_err = numpy.append(sap_bkg_err,kepstat.sumerr(work4)) sap_mean = scipy.stats.stats.nanmean(sap_flux) # coadd principal components if status == 0: pca_flux = numpy.zeros((len(sap_flux))) for i in range(nmask): if (i + 1) in pcaout: pca_flux = pca_flux + score[:,i] pca_flux += sap_mean # construct output primary extension if status == 0: hdu0 = pyfits.PrimaryHDU() for i in range(len(cards0)): if cards0[i].key not in hdu0.header.ascardlist().keys(): hdu0.header.update(cards0[i].key, cards0[i].value, cards0[i].comment) else: hdu0.header.ascardlist()[cards0[i].key].comment = cards0[i].comment status = kepkey.history(call,hdu0,outfile,logfile,verbose) outstr = HDUList(hdu0) # construct output light curve extension if status == 0: col1 = Column(name='TIME',format='D',unit='BJD - 2454833',array=time) col2 = Column(name='TIMECORR',format='E',unit='d',array=timecorr) col3 = Column(name='CADENCENO',format='J',array=cadenceno) col4 = Column(name='SAP_FLUX',format='E',array=sap_flux) col5 = Column(name='SAP_FLUX_ERR',format='E',array=sap_flux_err) col6 = Column(name='SAP_BKG',format='E',array=sap_bkg) col7 = Column(name='SAP_BKG_ERR',format='E',array=sap_bkg_err) col8 = Column(name='PDCSAP_FLUX',format='E',array=pdc_flux) col9 = Column(name='PDCSAP_FLUX_ERR',format='E',array=pdc_flux_err) col10 = Column(name='SAP_QUALITY',format='J',array=quality) col11 = Column(name='PSF_CENTR1',format='E',unit='pixel',array=psf_centr1) col12 = Column(name='PSF_CENTR1_ERR',format='E',unit='pixel',array=psf_centr1_err) col13 = Column(name='PSF_CENTR2',format='E',unit='pixel',array=psf_centr2) col14 = Column(name='PSF_CENTR2_ERR',format='E',unit='pixel',array=psf_centr2_err) col15 = Column(name='MOM_CENTR1',format='E',unit='pixel',array=mom_centr1) col16 = Column(name='MOM_CENTR1_ERR',format='E',unit='pixel',array=mom_centr1_err) col17 = Column(name='MOM_CENTR2',format='E',unit='pixel',array=mom_centr2) col18 = Column(name='MOM_CENTR2_ERR',format='E',unit='pixel',array=mom_centr2_err) col19 = Column(name='POS_CORR1',format='E',unit='pixel',array=pos_corr1) col20 = Column(name='POS_CORR2',format='E',unit='pixel',array=pos_corr2) cols = ColDefs([col1,col2,col3,col4,col5,col6,col7,col8,col9,col10,col11, \ col12,col13,col14,col15,col16,col17,col18,col19,col20]) hdu1 = new_table(cols) hdu1.header.update('TTYPE1','TIME','column title: data time stamps') hdu1.header.update('TFORM1','D','data type: float64') hdu1.header.update('TUNIT1','BJD - 2454833','column units: barycenter corrected JD') hdu1.header.update('TDISP1','D12.7','column display format') hdu1.header.update('TTYPE2','TIMECORR','column title: barycentric-timeslice correction') hdu1.header.update('TFORM2','E','data type: float32') hdu1.header.update('TUNIT2','d','column units: days') hdu1.header.update('TTYPE3','CADENCENO','column title: unique cadence number') hdu1.header.update('TFORM3','J','column format: signed integer32') hdu1.header.update('TTYPE4','SAP_FLUX','column title: aperture photometry flux') hdu1.header.update('TFORM4','E','column format: float32') hdu1.header.update('TUNIT4','e-/s','column units: electrons per second') hdu1.header.update('TTYPE5','SAP_FLUX_ERR','column title: aperture phot. flux error') hdu1.header.update('TFORM5','E','column format: float32') hdu1.header.update('TUNIT5','e-/s','column units: electrons per second (1-sigma)') hdu1.header.update('TTYPE6','SAP_BKG','column title: aperture phot. background flux') hdu1.header.update('TFORM6','E','column format: float32') hdu1.header.update('TUNIT6','e-/s','column units: electrons per second') hdu1.header.update('TTYPE7','SAP_BKG_ERR','column title: ap. phot. background flux error') hdu1.header.update('TFORM7','E','column format: float32') hdu1.header.update('TUNIT7','e-/s','column units: electrons per second (1-sigma)') hdu1.header.update('TTYPE8','PDCSAP_FLUX','column title: PDC photometry flux') hdu1.header.update('TFORM8','E','column format: float32') hdu1.header.update('TUNIT8','e-/s','column units: electrons per second') hdu1.header.update('TTYPE9','PDCSAP_FLUX_ERR','column title: PDC flux error') hdu1.header.update('TFORM9','E','column format: float32') hdu1.header.update('TUNIT9','e-/s','column units: electrons per second (1-sigma)') hdu1.header.update('TTYPE10','SAP_QUALITY','column title: aperture photometry quality flag') hdu1.header.update('TFORM10','J','column format: signed integer32') hdu1.header.update('TTYPE11','PSF_CENTR1','column title: PSF fitted column centroid') hdu1.header.update('TFORM11','E','column format: float32') hdu1.header.update('TUNIT11','pixel','column units: pixel') hdu1.header.update('TTYPE12','PSF_CENTR1_ERR','column title: PSF fitted column error') hdu1.header.update('TFORM12','E','column format: float32') hdu1.header.update('TUNIT12','pixel','column units: pixel') hdu1.header.update('TTYPE13','PSF_CENTR2','column title: PSF fitted row centroid') hdu1.header.update('TFORM13','E','column format: float32') hdu1.header.update('TUNIT13','pixel','column units: pixel') hdu1.header.update('TTYPE14','PSF_CENTR2_ERR','column title: PSF fitted row error') hdu1.header.update('TFORM14','E','column format: float32') hdu1.header.update('TUNIT14','pixel','column units: pixel') hdu1.header.update('TTYPE15','MOM_CENTR1','column title: moment-derived column centroid') hdu1.header.update('TFORM15','E','column format: float32') hdu1.header.update('TUNIT15','pixel','column units: pixel') hdu1.header.update('TTYPE16','MOM_CENTR1_ERR','column title: moment-derived column error') hdu1.header.update('TFORM16','E','column format: float32') hdu1.header.update('TUNIT16','pixel','column units: pixel') hdu1.header.update('TTYPE17','MOM_CENTR2','column title: moment-derived row centroid') hdu1.header.update('TFORM17','E','column format: float32') hdu1.header.update('TUNIT17','pixel','column units: pixel') hdu1.header.update('TTYPE18','MOM_CENTR2_ERR','column title: moment-derived row error') hdu1.header.update('TFORM18','E','column format: float32') hdu1.header.update('TUNIT18','pixel','column units: pixel') hdu1.header.update('TTYPE19','POS_CORR1','column title: col correction for vel. abbern') hdu1.header.update('TFORM19','E','column format: float32') hdu1.header.update('TUNIT19','pixel','column units: pixel') hdu1.header.update('TTYPE20','POS_CORR2','column title: row correction for vel. abbern') hdu1.header.update('TFORM20','E','column format: float32') hdu1.header.update('TUNIT20','pixel','column units: pixel') hdu1.header.update('EXTNAME','LIGHTCURVE','name of extension') for i in range(len(cards1)): if (cards1[i].key not in hdu1.header.ascardlist().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 if status == 0: hdu2 = ImageHDU(maskmap) for i in range(len(cards2)): if cards2[i].key not in hdu2.header.ascardlist().keys(): hdu2.header.update(cards2[i].key, cards2[i].value, cards2[i].comment) else: hdu2.header.ascardlist()[cards2[i].key].comment = cards2[i].comment outstr.append(hdu2) # construct principal component table if status == 0: cols = [] for i in range(nmask): colname = 'PC' + str(i + 1) col = Column(name=colname,format='E',unit='e-/s',array=score[:,i]) cols.append(col) hdu3 = new_table(ColDefs(cols)) hdu3.header.update('EXTNAME','PRINCIPAL_COMPONENTS','name of extension') for i in range(nmask): hdu3.header.update('TTYPE' + str(i + 1),'PC' + str(i + 1),'column title: principal component number' + str(i + 1)) hdu3.header.update('TFORM' + str(i + 1),'E','column format: float32') hdu3.header.update('TUNIT' + str(i + 1),'e-/s','column units: electrons per sec') outstr.append(hdu3) # write output file if status == 0: outstr.writeto(outfile,checksum=True) # close input structure if status == 0: status = kepio.closefits(instr,logfile,verbose) # plotting defaults if status == 0: 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: pylab.figure(figsize=[xsize,ysize]) pylab.clf() # clean up x-axis unit if status == 0: intime0 = float(int(tstart / 100) * 100.0) ptime = time + bjdref - intime0 xlab = 'BJD $-$ %d' % intime0 # clean up y-axis units if status == 0: pout = copy(score) 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 # plot window 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=[]) # plot principal components for i in range(nmask): pylab.plot(ptime,pout[:,i],linestyle='-',linewidth=lwidth) if not plotLatex: ylab = '10**%d electrons/sec' % nrm ylabel(ylab, {'color' : 'k'}) grid() # plot ranges pylab.xlim(xmin-xr*0.01,xmax+xr*0.01) pylab.ylim(ymin-yr*0.01,ymax+yr*0.01) # plot output data ax = pylab.axes([0.06,0.09,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() setp(labels, 'rotation', 90) # clean up y-axis units if status == 0: pout = copy(pca_flux) nrm = len(str(int(pout.max())))-1 pout = pout / 10**nrm ylab = '10$^%d$ e$^-$ s$^{-1}$' % nrm # data limits ymin = pout.min() ymax = pout.max() yr = ymax - ymin ptime = numpy.insert(ptime,[0],[ptime[0]]) ptime = numpy.append(ptime,[ptime[-1]]) pout = numpy.insert(pout,[0],[0.0]) pout = numpy.append(pout,0.0) # plot time coadded principal component series 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 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 cmdLine: pylab.show() else: pylab.ion() pylab.plot([]) pylab.ioff() # stop time if status == 0: kepmsg.clock('KEPPCA ended at',logfile,verbose) return
def kepextract(infile,maskfile,outfile,subback,clobber,verbose,logfile,status): # startup parameters status = 0 seterr(all="ignore") # log the call hashline = '----------------------------------------------------------------------------' kepmsg.log(logfile,hashline,verbose) call = 'KEPEXTRACT -- ' call += 'infile='+infile+' ' call += 'maskfile='+maskfile+' ' call += 'outfile='+outfile+' ' backgr = 'n' if (subback): backgr = 'y' call += 'background='+backgr+ ' ' 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('KEPEXTRACT 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 -- KEPEXTRACT: ' + outfile + ' exists. Use --clobber' status = kepmsg.err(logfile,message,verbose) # open input file status = 0 instr = pyfits.open(infile,mode='readonly',memmap=True) if status == 0: 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) # input file data if status == 0: cards0 = instr[0].header.cards cards1 = instr[1].header.cards cards2 = instr[2].header.cards table = instr[1].data[:] maskmap = copy(instr[2].data) # input table data if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, time, status = \ kepio.readTPF(infile,'TIME',logfile,verbose) time = numpy.array(time,dtype='float64') if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, timecorr, status = \ kepio.readTPF(infile,'TIMECORR',logfile,verbose) timecorr = numpy.array(timecorr,dtype='float32') if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, cadenceno, status = \ kepio.readTPF(infile,'CADENCENO',logfile,verbose) cadenceno = numpy.array(cadenceno,dtype='int') if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, raw_cnts, status = \ kepio.readTPF(infile,'RAW_CNTS',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, flux, status = \ kepio.readTPF(infile,'FLUX',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, flux_err, 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, flux_bkg, status = \ kepio.readTPF(infile,'FLUX_BKG',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, flux_bkg_err, status = \ kepio.readTPF(infile,'FLUX_BKG_ERR',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, cosmic_rays, status = \ kepio.readTPF(infile,'COSMIC_RAYS',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, quality, status = \ kepio.readTPF(infile,'QUALITY',logfile,verbose) quality = numpy.array(quality,dtype='int') if status == 0: try: pos_corr1 = numpy.array(table.field('POS_CORR1'),dtype='float64') # ---for FITS wave #2 except: pos_corr1 = empty(len(time)); pos_corr1[:] = numpy.nan # ---temporary before FITS wave #2 try: pos_corr2 = numpy.array(table.field('POS_CORR2'),dtype='float64') # ---for FITS wave #2 except: pos_corr2 = empty(len(time)); pos_corr2[:] = numpy.nan # ---temporary before FITS wave #2 # dummy columns for output file psf_centr1 = empty(len(time)); psf_centr1[:] = numpy.nan psf_centr1_err = empty(len(time)); psf_centr1_err[:] = numpy.nan psf_centr2 = empty(len(time)); psf_centr2[:] = numpy.nan psf_centr2_err = empty(len(time)); psf_centr2_err[:] = numpy.nan # mom_centr1 = empty(len(time)); mom_centr1[:] = numpy.nan mom_centr1_err = empty(len(time)); mom_centr1_err[:] = numpy.nan # mom_centr2 = empty(len(time)); mom_centr2[:] = numpy.nan mom_centr2_err = empty(len(time)); mom_centr2_err[:] = numpy.nan # read mask definition file if status == 0 and 'aper' not in maskfile.lower() and maskfile.lower() != 'all': maskx = array([],'int') masky = array([],'int') lines, status = kepio.openascii(maskfile,'r',logfile,verbose) for line in lines: line = line.strip().split('|') if len(line) == 6: y0 = int(line[3]) x0 = int(line[4]) line = line[5].split(';') for items in line: try: masky = append(masky,y0 + int(items.split(',')[0])) maskx = append(maskx,x0 + int(items.split(',')[1])) except: continue status = kepio.closeascii(lines,logfile,verbose) if len(maskx) == 0 or len(masky) == 0: message = 'ERROR -- KEPEXTRACT: ' + maskfile + ' contains no pixels.' status = kepmsg.err(logfile,message,verbose) # subimage physical WCS data if status == 0: crpix1p = cards2['CRPIX1P'].value crpix2p = cards2['CRPIX2P'].value crval1p = cards2['CRVAL1P'].value crval2p = cards2['CRVAL2P'].value cdelt1p = cards2['CDELT1P'].value cdelt2p = cards2['CDELT2P'].value # define new subimage bitmap... if status == 0 and 'aper' not in maskfile.lower() and maskfile.lower() != 'all': aperx = array([],'int') apery = array([],'int') aperb = array([],'int') for i in range(maskmap.shape[0]): for j in range(maskmap.shape[1]): aperx = append(aperx,crval1p + (j + 1 - crpix1p) * cdelt1p) apery = append(apery,crval2p + (i + 1 - crpix2p) * cdelt2p) if maskmap[i,j] == 0: aperb = append(aperb,0) else: aperb = append(aperb,1) maskmap[i,j] = 1 for k in range(len(maskx)): if aperx[-1] == maskx[k] and apery[-1] == masky[k]: aperb[-1] = 3 maskmap[i,j] = 3 # trap case where no aperture needs to be defined but pixel positions are still required for centroiding if status == 0 and maskfile.lower() == 'all': aperx = array([],'int') apery = array([],'int') for i in range(maskmap.shape[0]): for j in range(maskmap.shape[1]): aperx = append(aperx,crval1p + (j + 1 - crpix1p) * cdelt1p) apery = append(apery,crval2p + (i + 1 - crpix2p) * cdelt2p) # ...or use old subimage bitmap if status == 0 and 'aper' in maskfile.lower(): aperb = array([],'int') for i in range(maskmap.shape[0]): for j in range(maskmap.shape[1]): aperb = append(aperb,maskmap[i,j]) # ...or use all pixels if status == 0 and maskfile.lower() == 'all': aperb = array([],'int') for i in range(maskmap.shape[0]): for j in range(maskmap.shape[1]): if maskmap[i,j] == 0: aperb = append(aperb,0) else: aperb = append(aperb,3) maskmap[i,j] = 3 # subtract median pixel value for background? if status == 0: sky = array([],'float32') for i in range(len(time)): sky = append(sky,median(flux[i,:])) if not subback: sky[:] = 0.0 # legal mask defined? if status == 0: if len(aperb) == 0: message = 'ERROR -- KEPEXTRACT: no legal pixels within the subimage are defined.' status = kepmsg.err(logfile,message,verbose) # construct new table flux data if status == 0: naper = (aperb == 3).sum() ntime = len(time) sap_flux = array([],'float32') sap_flux_err = array([],'float32') sap_bkg = array([],'float32') sap_bkg_err = array([],'float32') raw_flux = array([],'float32') for i in range(len(time)): work1 = array([],'float64') work2 = array([],'float64') work3 = array([],'float64') work4 = array([],'float64') work5 = array([],'float64') for j in range(len(aperb)): if (aperb[j] == 3): work1 = append(work1,flux[i,j]-sky[i]) work2 = append(work2,flux_err[i,j]) work3 = append(work3,flux_bkg[i,j]) work4 = append(work4,flux_bkg_err[i,j]) work5 = append(work5,raw_cnts[i,j]) sap_flux = append(sap_flux,kepstat.sum(work1)) sap_flux_err = append(sap_flux_err,kepstat.sumerr(work2)) sap_bkg = append(sap_bkg,kepstat.sum(work3)) sap_bkg_err = append(sap_bkg_err,kepstat.sumerr(work4)) raw_flux = append(raw_flux,kepstat.sum(work5)) # construct new table moment data if status == 0: mom_centr1 = zeros(shape=(ntime)) mom_centr2 = zeros(shape=(ntime)) mom_centr1_err = zeros(shape=(ntime)) mom_centr2_err = zeros(shape=(ntime)) for i in range(ntime): xf = zeros(shape=(naper)) yf = zeros(shape=(naper)) f = zeros(shape=(naper)) xfe = zeros(shape=(naper)) yfe = zeros(shape=(naper)) fe = zeros(shape=(naper)) k = -1 for j in range(len(aperb)): if (aperb[j] == 3): k += 1 xf[k] = aperx[j] * flux[i,j] xfe[k] = aperx[j] * flux_err[i,j] yf[k] = apery[j] * flux[i,j] yfe[k] = apery[j] * flux_err[i,j] f[k] = flux[i,j] fe[k] = flux_err[i,j] xfsum = kepstat.sum(xf) yfsum = kepstat.sum(yf) fsum = kepstat.sum(f) xfsume = sqrt(kepstat.sum(square(xfe)) / naper) yfsume = sqrt(kepstat.sum(square(yfe)) / naper) fsume = sqrt(kepstat.sum(square(fe)) / naper) mom_centr1[i] = xfsum / fsum mom_centr2[i] = yfsum / fsum mom_centr1_err[i] = sqrt((xfsume / xfsum)**2 + ((fsume / fsum)**2)) mom_centr2_err[i] = sqrt((yfsume / yfsum)**2 + ((fsume / fsum)**2)) mom_centr1_err = mom_centr1_err * mom_centr1 mom_centr2_err = mom_centr2_err * mom_centr2 # construct new table PSF data if status == 0: psf_centr1 = zeros(shape=(ntime)) psf_centr2 = zeros(shape=(ntime)) psf_centr1_err = zeros(shape=(ntime)) psf_centr2_err = zeros(shape=(ntime)) modx = zeros(shape=(naper)) mody = zeros(shape=(naper)) k = -1 for j in range(len(aperb)): if (aperb[j] == 3): k += 1 modx[k] = aperx[j] mody[k] = apery[j] for i in range(ntime): modf = zeros(shape=(naper)) k = -1 guess = [mom_centr1[i], mom_centr2[i], nanmax(flux[i:]), 1.0, 1.0, 0.0, 0.0] for j in range(len(aperb)): if (aperb[j] == 3): k += 1 modf[k] = flux[i,j] args = (modx, mody, modf) ans = leastsq(kepfunc.PRFgauss2d,guess,args=args,xtol=1.0e-8,ftol=1.0e-4,full_output=True) s_sq = (ans[2]['fvec']**2).sum() / (ntime-len(guess)) psf_centr1[i] = ans[0][0] psf_centr2[i] = ans[0][1] try: psf_centr1_err[i] = sqrt(diag(ans[1] * s_sq))[0] except: psf_centr1_err[i] = numpy.nan try: psf_centr2_err[i] = sqrt(diag(ans[1] * s_sq))[1] except: psf_centr2_err[i] = numpy.nan # construct output primary extension if status == 0: 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 if status == 0: col1 = Column(name='TIME',format='D',unit='BJD - 2454833',array=time) col2 = Column(name='TIMECORR',format='E',unit='d',array=timecorr) col3 = Column(name='CADENCENO',format='J',array=cadenceno) col4 = Column(name='SAP_FLUX',format='E',array=sap_flux) col5 = Column(name='SAP_FLUX_ERR',format='E',array=sap_flux_err) col6 = Column(name='SAP_BKG',format='E',array=sap_bkg) col7 = Column(name='SAP_BKG_ERR',format='E',array=sap_bkg_err) col8 = Column(name='PDCSAP_FLUX',format='E',array=sap_flux) col9 = Column(name='PDCSAP_FLUX_ERR',format='E',array=sap_flux_err) col10 = Column(name='SAP_QUALITY',format='J',array=quality) col11 = Column(name='PSF_CENTR1',format='E',unit='pixel',array=psf_centr1) col12 = Column(name='PSF_CENTR1_ERR',format='E',unit='pixel',array=psf_centr1_err) col13 = Column(name='PSF_CENTR2',format='E',unit='pixel',array=psf_centr2) col14 = Column(name='PSF_CENTR2_ERR',format='E',unit='pixel',array=psf_centr2_err) col15 = Column(name='MOM_CENTR1',format='E',unit='pixel',array=mom_centr1) col16 = Column(name='MOM_CENTR1_ERR',format='E',unit='pixel',array=mom_centr1_err) col17 = Column(name='MOM_CENTR2',format='E',unit='pixel',array=mom_centr2) col18 = Column(name='MOM_CENTR2_ERR',format='E',unit='pixel',array=mom_centr2_err) col19 = Column(name='POS_CORR1',format='E',unit='pixel',array=pos_corr1) col20 = Column(name='POS_CORR2',format='E',unit='pixel',array=pos_corr2) col21 = Column(name='RAW_FLUX',format='E',array=raw_flux) cols = ColDefs([col1,col2,col3,col4,col5,col6,col7,col8,col9,col10,col11, \ col12,col13,col14,col15,col16,col17,col18,col19,col20,col21]) hdu1 = new_table(cols) hdu1.header.update('TTYPE1','TIME','column title: data time stamps') hdu1.header.update('TFORM1','D','data type: float64') hdu1.header.update('TUNIT1','BJD - 2454833','column units: barycenter corrected JD') hdu1.header.update('TDISP1','D12.7','column display format') hdu1.header.update('TTYPE2','TIMECORR','column title: barycentric-timeslice correction') hdu1.header.update('TFORM2','E','data type: float32') hdu1.header.update('TUNIT2','d','column units: days') hdu1.header.update('TTYPE3','CADENCENO','column title: unique cadence number') hdu1.header.update('TFORM3','J','column format: signed integer32') hdu1.header.update('TTYPE4','SAP_FLUX','column title: aperture photometry flux') hdu1.header.update('TFORM4','E','column format: float32') hdu1.header.update('TUNIT4','e-/s','column units: electrons per second') hdu1.header.update('TTYPE5','SAP_FLUX_ERR','column title: aperture phot. flux error') hdu1.header.update('TFORM5','E','column format: float32') hdu1.header.update('TUNIT5','e-/s','column units: electrons per second (1-sigma)') hdu1.header.update('TTYPE6','SAP_BKG','column title: aperture phot. background flux') hdu1.header.update('TFORM6','E','column format: float32') hdu1.header.update('TUNIT6','e-/s','column units: electrons per second') hdu1.header.update('TTYPE7','SAP_BKG_ERR','column title: ap. phot. background flux error') hdu1.header.update('TFORM7','E','column format: float32') hdu1.header.update('TUNIT7','e-/s','column units: electrons per second (1-sigma)') hdu1.header.update('TTYPE8','PDCSAP_FLUX','column title: PDC photometry flux') hdu1.header.update('TFORM8','E','column format: float32') hdu1.header.update('TUNIT8','e-/s','column units: electrons per second') hdu1.header.update('TTYPE9','PDCSAP_FLUX_ERR','column title: PDC flux error') hdu1.header.update('TFORM9','E','column format: float32') hdu1.header.update('TUNIT9','e-/s','column units: electrons per second (1-sigma)') hdu1.header.update('TTYPE10','SAP_QUALITY','column title: aperture photometry quality flag') hdu1.header.update('TFORM10','J','column format: signed integer32') hdu1.header.update('TTYPE11','PSF_CENTR1','column title: PSF fitted column centroid') hdu1.header.update('TFORM11','E','column format: float32') hdu1.header.update('TUNIT11','pixel','column units: pixel') hdu1.header.update('TTYPE12','PSF_CENTR1_ERR','column title: PSF fitted column error') hdu1.header.update('TFORM12','E','column format: float32') hdu1.header.update('TUNIT12','pixel','column units: pixel') hdu1.header.update('TTYPE13','PSF_CENTR2','column title: PSF fitted row centroid') hdu1.header.update('TFORM13','E','column format: float32') hdu1.header.update('TUNIT13','pixel','column units: pixel') hdu1.header.update('TTYPE14','PSF_CENTR2_ERR','column title: PSF fitted row error') hdu1.header.update('TFORM14','E','column format: float32') hdu1.header.update('TUNIT14','pixel','column units: pixel') hdu1.header.update('TTYPE15','MOM_CENTR1','column title: moment-derived column centroid') hdu1.header.update('TFORM15','E','column format: float32') hdu1.header.update('TUNIT15','pixel','column units: pixel') hdu1.header.update('TTYPE16','MOM_CENTR1_ERR','column title: moment-derived column error') hdu1.header.update('TFORM16','E','column format: float32') hdu1.header.update('TUNIT16','pixel','column units: pixel') hdu1.header.update('TTYPE17','MOM_CENTR2','column title: moment-derived row centroid') hdu1.header.update('TFORM17','E','column format: float32') hdu1.header.update('TUNIT17','pixel','column units: pixel') hdu1.header.update('TTYPE18','MOM_CENTR2_ERR','column title: moment-derived row error') hdu1.header.update('TFORM18','E','column format: float32') hdu1.header.update('TUNIT18','pixel','column units: pixel') hdu1.header.update('TTYPE19','POS_CORR1','column title: col correction for vel. abbern') hdu1.header.update('TFORM19','E','column format: float32') hdu1.header.update('TUNIT19','pixel','column units: pixel') hdu1.header.update('TTYPE20','POS_CORR2','column title: row correction for vel. abbern') hdu1.header.update('TFORM20','E','column format: float32') hdu1.header.update('TUNIT20','pixel','column units: pixel') hdu1.header.update('TTYPE21','RAW_FLUX','column title: raw aperture photometry flux') hdu1.header.update('TFORM21','E','column format: float32') hdu1.header.update('TUNIT21','e-/s','column units: electrons per second') hdu1.header.update('EXTNAME','LIGHTCURVE','name of extension') 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 if status == 0: 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 if status == 0: outstr.writeto(outfile,checksum=True) # close input structure if status == 0: status = kepio.closefits(instr,logfile,verbose) # end time kepmsg.clock('KEPEXTRACT finished at',logfile,verbose)
def keppca(infile,maskfile,outfile,components,plotpca,nreps,clobber,verbose,logfile,status,cmdLine=False): try: import mdp except: msg = 'ERROR -- KEPPCA: this task has an external python dependency to MDP, a Modular toolkit for Data Processing (http://mdp-toolkit.sourceforge.net). In order to take advantage of this PCA task, the user must first install MDP with their current python distribution. Note carefully that you may have more than python installation on your machine, and ensure that MDP is installed with the same version of python that the PyKE tools employ. Installation instructions for MDP can be found at the URL provided above.' status = kepmsg.err(None,msg,True) # startup parameters status = 0 labelsize = 32 ticksize = 18 xsize = 16 ysize = 10 lcolor = '#0000ff' lwidth = 1.0 fcolor = '#ffff00' falpha = 0.2 seterr(all="ignore") # log the call if status == 0: hashline = '----------------------------------------------------------------------------' kepmsg.log(logfile,hashline,verbose) call = 'KEPPCA -- ' call += 'infile='+infile+' ' call += 'maskfile='+maskfile+' ' call += 'outfile='+outfile+' ' call += 'components='+components+' ' ppca = 'n' if (plotpca): ppca = 'y' call += 'plotpca='+ppca+ ' ' call += 'nmaps='+str(nreps)+' ' 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 if status == 0: kepmsg.clock('KEPPCA started at',logfile,verbose) # test log file if status == 0: logfile = kepmsg.test(logfile) # clobber output file if status == 0: if clobber: status = kepio.clobber(outfile,logfile,verbose) if kepio.fileexists(outfile): message = 'ERROR -- KEPPCA: ' + outfile + ' exists. Use clobber=yes' status = kepmsg.err(logfile,message,verbose) # Set output file names - text file with data and plot if status == 0: dataout = copy(outfile) repname = re.sub('.fits','.png',outfile) # open input file if status == 0: instr = pyfits.open(infile,mode='readonly',memmap=True) tstart, tstop, bjdref, cadence, status = kepio.timekeys(instr,infile,logfile,verbose,status) # open TPF FITS file if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, barytime, status = \ kepio.readTPF(infile,'TIME',logfile,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, flux_bkg, status = \ kepio.readTPF(infile,'FLUX_BKG',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, flux_bkg_err, status = \ kepio.readTPF(infile,'FLUX_BKG_ERR',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, qual, status = \ kepio.readTPF(infile,'QUALITY',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, pcorr1, status = \ kepio.readTPF(infile,'POS_CORR1',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, pcorr2, status = \ kepio.readTPF(infile,'POS_CORR2',logfile,verbose) # Save original data dimensions, in case of using maskfile if status == 0: xdimorig = xdim ydimorig = ydim # read mask definition file if it has been supplied if status == 0 and 'aper' not in maskfile.lower() and maskfile.lower() != 'all': maskx = array([],'int') masky = array([],'int') lines, status = kepio.openascii(maskfile,'r',logfile,verbose) for line in lines: line = line.strip().split('|') if len(line) == 6: y0 = int(line[3]) x0 = int(line[4]) line = line[5].split(';') for items in line: try: masky = numpy.append(masky,y0 + int(items.split(',')[0])) maskx = numpy.append(maskx,x0 + int(items.split(',')[1])) except: continue status = kepio.closeascii(lines,logfile,verbose) if len(maskx) == 0 or len(masky) == 0: message = 'ERROR -- KEPPCA: ' + maskfile + ' contains no pixels.' status = kepmsg.err(logfile,message,verbose) xdim = max(maskx) - min(maskx) + 1 # Find largest x dimension of mask ydim = max(masky) - min(masky) + 1 # Find largest y dimension of mask # pad mask to ensure it is rectangular workx = array([],'int') worky = array([],'int') for ip in arange(min(maskx),max(maskx) + 1): for jp in arange(min(masky),max(masky) + 1): workx = append(workx,ip) worky = append(worky,jp) maskx = workx masky = worky # define new subimage bitmap... if status == 0 and maskfile.lower() != 'all': aperx = numpy.array([],'int') apery = numpy.array([],'int') aperb = maskx - x0 + xdimorig * (masky - y0) # aperb is an array that contains the pixel numbers in the mask npix = len(aperb) # ...or use all pixels if status == 0 and maskfile.lower() == 'all': npix = xdimorig*ydimorig aperb = array([],'int') aperb = numpy.r_[0:npix] # legal mask defined? if status == 0: if len(aperb) == 0: message = 'ERROR -- KEPPCA: no legal pixels within the subimage are defined.' status = kepmsg.err(logfile,message,verbose) # Identify principal components desired if status == 0: pcaout = [] txt = components.strip().split(',') for work1 in txt: try: pcaout.append(int(work1.strip())) except: work2 = work1.strip().split('-') try: for work3 in range(int(work2[0]),int(work2[1]) + 1): pcaout.append(work3) except: message = 'ERROR -- KEPPCA: cannot understand principal component list requested' status = kepmsg.err(logfile,message,verbose) if status == 0: pcaout = set(sort(pcaout)) pcarem = array(list(pcaout))-1 # The list of pca component numbers to be removed # Initialize arrays and variables, and apply pixel mask to the data if status == 0: ntim = 0 time = numpy.array([],dtype='float64') timecorr = numpy.array([],dtype='float32') cadenceno = numpy.array([],dtype='int') pixseries = numpy.array([],dtype='float32') errseries = numpy.array([],dtype='float32') bkgseries = numpy.array([],dtype='float32') berseries = numpy.array([],dtype='float32') quality = numpy.array([],dtype='float32') pos_corr1 = numpy.array([],dtype='float32') pos_corr2 = numpy.array([],dtype='float32') nrows = numpy.size(fluxpixels,0) # Apply the pixel mask so we are left with only the desired pixels if status == 0: pixseriesb = fluxpixels[:,aperb] errseriesb = errpixels[:,aperb] bkgseriesb = flux_bkg[:,aperb] berseriesb = flux_bkg_err[:,aperb] # Read in the data to various arrays if status == 0: for i in range(nrows): if qual[i] < 10000 and \ numpy.isfinite(barytime[i]) and \ numpy.isfinite(fluxpixels[i,int(ydim*xdim/2+0.5)]) and \ numpy.isfinite(fluxpixels[i,1+int(ydim*xdim/2+0.5)]): ntim += 1 time = numpy.append(time,barytime[i]) timecorr = numpy.append(timecorr,tcorr[i]) cadenceno = numpy.append(cadenceno,cadno[i]) pixseries = numpy.append(pixseries,pixseriesb[i]) errseries = numpy.append(errseries,errseriesb[i]) bkgseries = numpy.append(bkgseries,bkgseriesb[i]) berseries = numpy.append(berseries,berseriesb[i]) quality = numpy.append(quality,qual[i]) pos_corr1 = numpy.append(pos_corr1,pcorr1[i]) pos_corr2 = numpy.append(pos_corr2,pcorr2[i]) pixseries = numpy.reshape(pixseries,(ntim,npix)) errseries = numpy.reshape(errseries,(ntim,npix)) bkgseries = numpy.reshape(bkgseries,(ntim,npix)) berseries = numpy.reshape(berseries,(ntim,npix)) tmp = numpy.median(pixseries,axis=1) for i in range(len(tmp)): pixseries[i] = pixseries[i] - tmp[i] # Figure out which pixels are undefined/nan and remove them. Keep track for adding back in later if status == 0: nanpixels = numpy.array([],dtype='int') i = 0 while (i < npix): if numpy.isnan(pixseries[0,i]): nanpixels = numpy.append(nanpixels,i) npix = npix - 1 i = i + 1 pixseries = numpy.delete(pixseries,nanpixels,1) errseries = numpy.delete(errseries,nanpixels,1) pixseries[numpy.isnan(pixseries)] = random.gauss(100,10) errseries[numpy.isnan(errseries)] = 10 # Compute statistical weights, means, standard deviations if status == 0: weightseries = (pixseries/errseries)**2 pixMean = numpy.average(pixseries,axis=0,weights=weightseries) pixStd = numpy.std(pixseries,axis=0) # Normalize the input by subtracting the mean and divising by the standard deviation. # This makes it a correlation-based PCA, which is what we want. if status == 0: pixseriesnorm = (pixseries - pixMean)/pixStd # Number of principal components to compute. Setting it equal to the number of pixels if status == 0: nvecin = npix # Run PCA using the MDP Whitening PCA, which produces normalized PCA components (zero mean and unit variance) if status == 0: pcan = mdp.nodes.WhiteningNode(svd=True) pcar = pcan.execute(pixseriesnorm) eigvec = pcan.get_recmatrix() model = pcar # Re-insert nan columns as zeros if status == 0: for i in range(0,len(nanpixels)): nanpixels[i] = nanpixels[i]-i eigvec = numpy.insert(eigvec,nanpixels,0,1) pixMean = numpy.insert(pixMean,nanpixels,0,0) # Make output eigenvectors (correlation images) into xpix by ypix images if status == 0: eigvec = eigvec.reshape(nvecin,ydim,xdim) # Calculate sum of all pixels to display as raw lightcurve and other quantities if status == 0: pixseriessum = sum(pixseries,axis=1) nrem=len(pcarem) # Number of components to remove nplot = npix # Number of pcas to plot - currently set to plot all components, but could set # nplot = nrem to just plot as many components as is being removed # Subtract components by fitting them to the summed light curve if status == 0: x0 = numpy.tile(-1.0,1) for k in range(0,nrem): def f(x): fluxcor = pixseriessum for k in range(0,len(x)): fluxcor = fluxcor - x[k]*model[:,pcarem[k]] return mad(fluxcor) if k==0: x0 = array([-1.0]) else: x0 = numpy.append(x0,1.0) myfit = scipy.optimize.fmin(f,x0,maxiter=50000,maxfun=50000,disp=False) x0 = myfit # Now that coefficients for all components have been found, subtract them to produce a calibrated time-series, # and then divide by the robust mean to produce a normalized time series as well if status == 0: c = myfit fluxcor = pixseriessum for k in range(0,nrem): fluxcor = fluxcor - c[k]*model[:,pcarem[k]] normfluxcor = fluxcor/mean(reject_outliers(fluxcor,2)) # input file data if status == 0: cards0 = instr[0].header.cards cards1 = instr[1].header.cards cards2 = instr[2].header.cards table = instr[1].data[:] maskmap = copy(instr[2].data) # subimage physical WCS data if status == 0: crpix1p = cards2['CRPIX1P'].value crpix2p = cards2['CRPIX2P'].value crval1p = cards2['CRVAL1P'].value crval2p = cards2['CRVAL2P'].value cdelt1p = cards2['CDELT1P'].value cdelt2p = cards2['CDELT2P'].value # dummy columns for output file if status == 0: sap_flux_err = numpy.empty(len(time)); sap_flux_err[:] = numpy.nan sap_bkg = numpy.empty(len(time)); sap_bkg[:] = numpy.nan sap_bkg_err = numpy.empty(len(time)); sap_bkg_err[:] = numpy.nan pdc_flux = numpy.empty(len(time)); pdc_flux[:] = numpy.nan pdc_flux_err = numpy.empty(len(time)); pdc_flux_err[:] = numpy.nan psf_centr1 = numpy.empty(len(time)); psf_centr1[:] = numpy.nan psf_centr1_err = numpy.empty(len(time)); psf_centr1_err[:] = numpy.nan psf_centr2 = numpy.empty(len(time)); psf_centr2[:] = numpy.nan psf_centr2_err = numpy.empty(len(time)); psf_centr2_err[:] = numpy.nan mom_centr1 = numpy.empty(len(time)); mom_centr1[:] = numpy.nan mom_centr1_err = numpy.empty(len(time)); mom_centr1_err[:] = numpy.nan mom_centr2 = numpy.empty(len(time)); mom_centr2[:] = numpy.nan mom_centr2_err = numpy.empty(len(time)); mom_centr2_err[:] = numpy.nan # mask bitmap if status == 0 and 'aper' not in maskfile.lower() and maskfile.lower() != 'all': for i in range(maskmap.shape[0]): for j in range(maskmap.shape[1]): aperx = append(aperx,crval1p + (j + 1 - crpix1p) * cdelt1p) apery = append(apery,crval2p + (i + 1 - crpix2p) * cdelt2p) if maskmap[i,j] == 0: pass else: maskmap[i,j] = 1 for k in range(len(maskx)): if aperx[-1] == maskx[k] and apery[-1] == masky[k]: maskmap[i,j] = 3 # construct output primary extension if status == 0: hdu0 = pyfits.PrimaryHDU() for i in range(len(cards0)): if cards0[i].keyword not in hdu0.header.keys(): hdu0.header[cards0[i].keyword] = (cards0[i].value, cards0[i].comment) else: hdu0.header.cards[cards0[i].keyword].comment = cards0[i].comment status = kepkey.history(call,hdu0,outfile,logfile,verbose) outstr = HDUList(hdu0) # construct output light curve extension if status == 0: col1 = Column(name='TIME',format='D',unit='BJD - 2454833',array=time) col2 = Column(name='TIMECORR',format='E',unit='d',array=timecorr) col3 = Column(name='CADENCENO',format='J',array=cadenceno) col4 = Column(name='SAP_FLUX',format='E',unit='e-/s',array=pixseriessum) col5 = Column(name='SAP_FLUX_ERR',format='E',unit='e-/s',array=sap_flux_err) col6 = Column(name='SAP_BKG',format='E',unit='e-/s',array=sap_bkg) col7 = Column(name='SAP_BKG_ERR',format='E',unit='e-/s',array=sap_bkg_err) col8 = Column(name='PDCSAP_FLUX',format='E',unit='e-/s',array=pdc_flux) col9 = Column(name='PDCSAP_FLUX_ERR',format='E',unit='e-/s',array=pdc_flux_err) col10 = Column(name='SAP_QUALITY',format='J',array=quality) col11 = Column(name='PSF_CENTR1',format='E',unit='pixel',array=psf_centr1) col12 = Column(name='PSF_CENTR1_ERR',format='E',unit='pixel',array=psf_centr1_err) col13 = Column(name='PSF_CENTR2',format='E',unit='pixel',array=psf_centr2) col14 = Column(name='PSF_CENTR2_ERR',format='E',unit='pixel',array=psf_centr2_err) col15 = Column(name='MOM_CENTR1',format='E',unit='pixel',array=mom_centr1) col16 = Column(name='MOM_CENTR1_ERR',format='E',unit='pixel',array=mom_centr1_err) col17 = Column(name='MOM_CENTR2',format='E',unit='pixel',array=mom_centr2) col18 = Column(name='MOM_CENTR2_ERR',format='E',unit='pixel',array=mom_centr2_err) col19 = Column(name='POS_CORR1',format='E',unit='pixel',array=pos_corr1) col20 = Column(name='POS_CORR2',format='E',unit='pixel',array=pos_corr2) col21 = Column(name='PCA_FLUX',format='E',unit='e-/s',array=fluxcor) col22 = Column(name='PCA_FLUX_NRM',format='E',array=normfluxcor) cols = ColDefs([col1,col2,col3,col4,col5,col6,col7,col8,col9,col10,col11, \ col12,col13,col14,col15,col16,col17,col18,col19,col20,col21,col22]) hdu1 = new_table(cols) hdu1.header['TTYPE1'] = ('TIME','column title: data time stamps') hdu1.header['TFORM1'] = ('D','data type: float64') hdu1.header['TUNIT1'] = ('BJD - 2454833','column units: barycenter corrected JD') hdu1.header['TDISP1'] = ('D12.7','column display format') hdu1.header['TTYPE2'] = ('TIMECORR','column title: barycentric-timeslice correction') hdu1.header['TFORM2'] = ('E','data type: float32') hdu1.header['TUNIT2'] = ('d','column units: days') hdu1.header['TTYPE3'] = ('CADENCENO','column title: unique cadence number') hdu1.header['TFORM3'] = ('J','column format: signed integer32') hdu1.header['TTYPE4'] = ('SAP_FLUX','column title: aperture photometry flux') hdu1.header['TFORM4'] = ('E','column format: float32') hdu1.header['TUNIT4'] = ('e-/s','column units: electrons per second') hdu1.header['TTYPE5'] = ('SAP_FLUX_ERR','column title: aperture phot. flux error') hdu1.header['TFORM5'] = ('E','column format: float32') hdu1.header['TUNIT5'] = ('e-/s','column units: electrons per second (1-sigma)') hdu1.header['TTYPE6'] = ('SAP_BKG','column title: aperture phot. background flux') hdu1.header['TFORM6'] = ('E','column format: float32') hdu1.header['TUNIT6'] = ('e-/s','column units: electrons per second') hdu1.header['TTYPE7'] = ('SAP_BKG_ERR','column title: ap. phot. background flux error') hdu1.header['TFORM7'] = ('E','column format: float32') hdu1.header['TUNIT7'] = ('e-/s','column units: electrons per second (1-sigma)') hdu1.header['TTYPE8'] = ('PDCSAP_FLUX','column title: PDC photometry flux') hdu1.header['TFORM8'] = ('E','column format: float32') hdu1.header['TUNIT8'] = ('e-/s','column units: electrons per second') hdu1.header['TTYPE9'] = ('PDCSAP_FLUX_ERR','column title: PDC flux error') hdu1.header['TFORM9'] = ('E','column format: float32') hdu1.header['TUNIT9'] = ('e-/s','column units: electrons per second (1-sigma)') hdu1.header['TTYPE10'] = ('SAP_QUALITY','column title: aperture photometry quality flag') hdu1.header['TFORM10'] = ('J','column format: signed integer32') hdu1.header['TTYPE11'] = ('PSF_CENTR1','column title: PSF fitted column centroid') hdu1.header['TFORM11'] = ('E','column format: float32') hdu1.header['TUNIT11'] = ('pixel','column units: pixel') hdu1.header['TTYPE12'] = ('PSF_CENTR1_ERR','column title: PSF fitted column error') hdu1.header['TFORM12'] = ('E','column format: float32') hdu1.header['TUNIT12'] = ('pixel','column units: pixel') hdu1.header['TTYPE13'] = ('PSF_CENTR2','column title: PSF fitted row centroid') hdu1.header['TFORM13'] = ('E','column format: float32') hdu1.header['TUNIT13'] = ('pixel','column units: pixel') hdu1.header['TTYPE14'] = ('PSF_CENTR2_ERR','column title: PSF fitted row error') hdu1.header['TFORM14'] = ('E','column format: float32') hdu1.header['TUNIT14'] = ('pixel','column units: pixel') hdu1.header['TTYPE15'] = ('MOM_CENTR1','column title: moment-derived column centroid') hdu1.header['TFORM15'] = ('E','column format: float32') hdu1.header['TUNIT15'] = ('pixel','column units: pixel') hdu1.header['TTYPE16'] = ('MOM_CENTR1_ERR','column title: moment-derived column error') hdu1.header['TFORM16'] = ('E','column format: float32') hdu1.header['TUNIT16'] = ('pixel','column units: pixel') hdu1.header['TTYPE17'] = ('MOM_CENTR2','column title: moment-derived row centroid') hdu1.header['TFORM17'] = ('E','column format: float32') hdu1.header['TUNIT17'] = ('pixel','column units: pixel') hdu1.header['TTYPE18'] = ('MOM_CENTR2_ERR','column title: moment-derived row error') hdu1.header['TFORM18'] = ('E','column format: float32') hdu1.header['TUNIT18'] = ('pixel','column units: pixel') hdu1.header['TTYPE19'] = ('POS_CORR1','column title: col correction for vel. abbern') hdu1.header['TFORM19'] = ('E','column format: float32') hdu1.header['TUNIT19'] = ('pixel','column units: pixel') hdu1.header['TTYPE20'] = ('POS_CORR2','column title: row correction for vel. abbern') hdu1.header['TFORM20'] = ('E','column format: float32') hdu1.header['TUNIT20'] = ('pixel','column units: pixel') hdu1.header['TTYPE21'] = ('PCA_FLUX','column title: PCA-corrected flux') hdu1.header['TFORM21'] = ('E','column format: float32') hdu1.header['TUNIT21'] = ('pixel','column units: e-/s') hdu1.header['TTYPE22'] = ('PCA_FLUX_NRM','column title: normalized PCA-corrected flux') hdu1.header['TFORM22'] = ('E','column format: float32') hdu1.header['EXTNAME'] = ('LIGHTCURVE','name of extension') for i in range(len(cards1)): if (cards1[i].keyword not in hdu1.header.keys() and cards1[i].keyword[: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[cards1[i].keyword] = (cards1[i].value, cards1[i].comment) outstr.append(hdu1) # construct output mask bitmap extension if status == 0: hdu2 = ImageHDU(maskmap) for i in range(len(cards2)): if cards2[i].keyword not in hdu2.header.keys(): hdu2.header[cards2[i].keyword] = (cards2[i].value, cards2[i].comment) else: hdu2.header.cards[cards2[i].keyword].comment = cards2[i].comment outstr.append(hdu2) # construct principal component table if status == 0: cols = [Column(name='TIME',format='E',unit='BJD - 2454833',array=time)] for i in range(len(pcar[0,:])): colname = 'PC' + str(i + 1) col = Column(name=colname,format='E',array=pcar[:,i]) cols.append(col) hdu3 = new_table(ColDefs(cols)) hdu3.header['EXTNAME'] = ('PRINCIPAL_COMPONENTS','name of extension') hdu3.header['TTYPE1'] = ('TIME','column title: data time stamps') hdu3.header['TFORM1'] = ('D','data type: float64') hdu3.header['TUNIT1'] = ('BJD - 2454833','column units: barycenter corrected JD') hdu3.header['TDISP1'] = ('D12.7','column display format') for i in range(len(pcar[0,:])): hdu3.header['TTYPE' + str(i + 2)] = \ ('PC' + str(i + 1), 'column title: principal component number' + str(i + 1)) hdu3.header['TFORM' + str(i + 2)] = ('E','column format: float32') outstr.append(hdu3) # write output file if status == 0: outstr.writeto(outfile) # close input structure if status == 0: status = kepio.closefits(instr,logfile,verbose) # Create PCA report if status == 0 and plotpca: npp = 7 # Number of plots per page l = 1 repcnt = 1 for k in range(nreps): # First plot of every pagewith flux image, flux and calibrated time series status = kepplot.define(16,12,logfile,verbose) if (k % (npp - 1) == 0): pylab.figure(figsize=[10,16]) subplot2grid((npp,6),(0,0), colspan=2) # imshow(log10(pixMean.reshape(xdim,ydim).T-min(pixMean)+1),interpolation="nearest",cmap='RdYlBu') imshow(log10(flipud(pixMean.reshape(ydim,xdim))-min(pixMean)+1),interpolation="nearest",cmap='RdYlBu') xticks([]) yticks([]) ax1 = subplot2grid((npp,6),(0,2), colspan=4) px = copy(time) + bjdref py = copy(pixseriessum) px, xlab, status = kepplot.cleanx(px,logfile,verbose) py, ylab, status = kepplot.cleany(py,1.0,logfile,verbose) kepplot.RangeOfPlot(px,py,0.01,False) kepplot.plot1d(px,py,cadence,lcolor,lwidth,fcolor,falpha,True) py = copy(fluxcor) py, ylab, status = kepplot.cleany(py,1.0,logfile,verbose) plot(px,py,marker='.',color='r',linestyle='',markersize=1.0) kepplot.labels('',re.sub('\)','',re.sub('Flux \(','',ylab)),'k',18) grid() setp(ax1.get_xticklabels(), visible=False) # plot principal components subplot2grid((npp,6),(l,0), colspan=2) imshow(eigvec[k],interpolation="nearest",cmap='RdYlBu') xlim(-0.5,xdim-0.5) ylim(-0.5,ydim-0.5) xticks([]) yticks([]) # The last plot on the page that should have the xlabel if ( k% (npp - 1) == npp - 2 or k == nvecin - 1): subplot2grid((npp,6),(l,2), colspan=4) py = copy(model[:,k]) kepplot.RangeOfPlot(px,py,0.01,False) kepplot.plot1d(px,py,cadence,'r',lwidth,'g',falpha,True) kepplot.labels(xlab,'PC ' + str(k+1),'k',18) pylab.grid() pylab.tight_layout() l = 1 pylab.savefig(re.sub('.png','_%d.png' % repcnt,repname)) if not cmdLine: kepplot.render(cmdLine) repcnt += 1 # The other plots on the page that should have no xlabel else: ax2 = subplot2grid((npp,6),(l,2), colspan=4) py = copy(model[:,k]) kepplot.RangeOfPlot(px,py,0.01,False) kepplot.plot1d(px,py,cadence,'r',lwidth,'g',falpha,True) kepplot.labels('','PC ' + str(k+1),'k',18) grid() setp(ax2.get_xticklabels(), visible=False) pylab.tight_layout() l=l+1 pylab.savefig(re.sub('.png','_%d.png' % repcnt,repname)) if not cmdLine: kepplot.render(cmdLine) # plot style and size if status == 0 and plotpca: status = kepplot.define(labelsize,ticksize,logfile,verbose) pylab.figure(figsize=[xsize,ysize]) pylab.clf() # plot aperture photometry and PCA corrected data if status == 0 and plotpca: ax = kepplot.location([0.06,0.54,0.93,0.43]) px = copy(time) + bjdref py = copy(pixseriessum) px, xlab, status = kepplot.cleanx(px,logfile,verbose) py, ylab, status = kepplot.cleany(py,1.0,logfile,verbose) kepplot.RangeOfPlot(px,py,0.01,False) kepplot.plot1d(px,py,cadence,lcolor,lwidth,fcolor,falpha,True) py = copy(fluxcor) py, ylab, status = kepplot.cleany(py,1.0,logfile,verbose) kepplot.plot1d(px,py,cadence,'r',2,fcolor,0.0,True) pylab.setp(pylab.gca(),xticklabels=[]) kepplot.labels('',ylab,'k',24) pylab.grid() # plot aperture photometry and PCA corrected data if status == 0 and plotpca: ax = kepplot.location([0.06,0.09,0.93,0.43]) yr = array([],'float32') npc = min([6,nrem]) for i in range(npc-1,-1,-1): py = pcar[:,i] * c[i] py, ylab, status = kepplot.cleany(py,1.0,logfile,verbose) cl = float(i) / (float(npc)) kepplot.plot1d(px,py,cadence,[1.0-cl,0.0,cl],2,fcolor,0.0,True) yr = append(yr,py) y1 = max(yr) y2 = -min(yr) kepplot.RangeOfPlot(px,array([-y1,y1,-y2,y2]),0.01,False) kepplot.labels(xlab,'Principal Components','k',24) pylab.grid() # save plot to file if status == 0 and plotpca: pylab.savefig(repname) # render plot if status == 0 and plotpca: kepplot.render(cmdLine) # stop time if status == 0: kepmsg.clock('KEPPCA ended at',logfile,verbose) return
def kepextract(infile,maskfile,outfile,subback,clobber,verbose,logfile,status): # startup parameters status = 0 seterr(all="ignore") # log the call hashline = '----------------------------------------------------------------------------' kepmsg.log(logfile,hashline,verbose) call = 'KEPEXTRACT -- ' call += 'infile='+infile+' ' call += 'maskfile='+maskfile+' ' call += 'outfile='+outfile+' ' backgr = 'n' if (subback): backgr = 'y' call += 'background='+backgr+ ' ' 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('KEPEXTRACT 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 -- KEPEXTRACT: ' + outfile + ' exists. Use --clobber' status = kepmsg.err(logfile,message,verbose) # open input file status = 0 instr = pyfits.open(infile,mode='readonly',memmap=True) if status == 0: 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) # input file data if status == 0: cards0 = instr[0].header.cards cards1 = instr[1].header.cards cards2 = instr[2].header.cards table = instr[1].data[:] maskmap = copy(instr[2].data) # input table data if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, time, status = \ kepio.readTPF(infile,'TIME',logfile,verbose) time = numpy.array(time,dtype='float64') if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, timecorr, status = \ kepio.readTPF(infile,'TIMECORR',logfile,verbose) timecorr = numpy.array(timecorr,dtype='float32') if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, cadenceno, status = \ kepio.readTPF(infile,'CADENCENO',logfile,verbose) cadenceno = numpy.array(cadenceno,dtype='int') if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, raw_cnts, status = \ kepio.readTPF(infile,'RAW_CNTS',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, flux, status = \ kepio.readTPF(infile,'FLUX',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, flux_err, 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, flux_bkg, status = \ kepio.readTPF(infile,'FLUX_BKG',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, flux_bkg_err, status = \ kepio.readTPF(infile,'FLUX_BKG_ERR',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, cosmic_rays, status = \ kepio.readTPF(infile,'COSMIC_RAYS',logfile,verbose) if status == 0: kepid, channel, skygroup, module, output, quarter, season, \ ra, dec, column, row, kepmag, xdim, ydim, quality, status = \ kepio.readTPF(infile,'QUALITY',logfile,verbose) quality = numpy.array(quality,dtype='int') if status == 0: try: pos_corr1 = numpy.array(table.field('POS_CORR1'),dtype='float64') # ---for FITS wave #2 except: pos_corr1 = empty(len(time)); pos_corr1[:] = numpy.nan # ---temporary before FITS wave #2 try: pos_corr2 = numpy.array(table.field('POS_CORR2'),dtype='float64') # ---for FITS wave #2 except: pos_corr2 = empty(len(time)); pos_corr2[:] = numpy.nan # ---temporary before FITS wave #2 # dummy columns for output file psf_centr1 = empty(len(time)); psf_centr1[:] = numpy.nan psf_centr1_err = empty(len(time)); psf_centr1_err[:] = numpy.nan psf_centr2 = empty(len(time)); psf_centr2[:] = numpy.nan psf_centr2_err = empty(len(time)); psf_centr2_err[:] = numpy.nan # mom_centr1 = empty(len(time)); mom_centr1[:] = numpy.nan mom_centr1_err = empty(len(time)); mom_centr1_err[:] = numpy.nan # mom_centr2 = empty(len(time)); mom_centr2[:] = numpy.nan mom_centr2_err = empty(len(time)); mom_centr2_err[:] = numpy.nan # read mask definition file if status == 0 and 'aper' not in maskfile.lower() and maskfile.lower() != 'all': maskx = array([],'int') masky = array([],'int') lines, status = kepio.openascii(maskfile,'r',logfile,verbose) for line in lines: line = line.strip().split('|') if len(line) == 6: y0 = int(line[3]) x0 = int(line[4]) line = line[5].split(';') for items in line: try: masky = append(masky,y0 + int(items.split(',')[0])) maskx = append(maskx,x0 + int(items.split(',')[1])) except: continue status = kepio.closeascii(lines,logfile,verbose) if len(maskx) == 0 or len(masky) == 0: message = 'ERROR -- KEPEXTRACT: ' + maskfile + ' contains no pixels.' status = kepmsg.err(logfile,message,verbose) # subimage physical WCS data if status == 0: crpix1p = cards2['CRPIX1P'].value crpix2p = cards2['CRPIX2P'].value crval1p = cards2['CRVAL1P'].value crval2p = cards2['CRVAL2P'].value cdelt1p = cards2['CDELT1P'].value cdelt2p = cards2['CDELT2P'].value # define new subimage bitmap... if status == 0 and 'aper' not in maskfile.lower() and maskfile.lower() != 'all': aperx = array([],'int') apery = array([],'int') aperb = array([],'int') for i in range(maskmap.shape[0]): for j in range(maskmap.shape[1]): aperx = append(aperx,crval1p + (j + 1 - crpix1p) * cdelt1p) apery = append(apery,crval2p + (i + 1 - crpix2p) * cdelt2p) if maskmap[i,j] == 0: aperb = append(aperb,0) else: aperb = append(aperb,1) maskmap[i,j] = 1 for k in range(len(maskx)): if aperx[-1] == maskx[k] and apery[-1] == masky[k]: aperb[-1] = 3 maskmap[i,j] = 3 # trap case where no aperture needs to be defined but pixel positions are still required for centroiding if status == 0 and maskfile.lower() == 'all': aperx = array([],'int') apery = array([],'int') for i in range(maskmap.shape[0]): for j in range(maskmap.shape[1]): aperx = append(aperx,crval1p + (j + 1 - crpix1p) * cdelt1p) apery = append(apery,crval2p + (i + 1 - crpix2p) * cdelt2p) # ...or use old subimage bitmap if status == 0 and 'aper' in maskfile.lower(): aperx = array([],'int') apery = array([],'int') aperb = array([],'int') for i in range(maskmap.shape[0]): for j in range(maskmap.shape[1]): aperb = append(aperb,maskmap[i,j]) aperx = append(aperx,crval1p + (j + 1 - crpix1p) * cdelt1p) apery = append(apery,crval2p + (i + 1 - crpix2p) * cdelt2p) # ...or use all pixels if status == 0 and maskfile.lower() == 'all': aperb = array([],'int') for i in range(maskmap.shape[0]): for j in range(maskmap.shape[1]): if maskmap[i,j] == 0: aperb = append(aperb,0) else: aperb = append(aperb,3) maskmap[i,j] = 3 # subtract median pixel value for background? if status == 0: sky = array([],'float32') for i in range(len(time)): sky = append(sky,median(flux[i,:])) if not subback: sky[:] = 0.0 # legal mask defined? if status == 0: if len(aperb) == 0: message = 'ERROR -- KEPEXTRACT: no legal pixels within the subimage are defined.' status = kepmsg.err(logfile,message,verbose) # construct new table flux data if status == 0: naper = (aperb == 3).sum() ntime = len(time) sap_flux = array([],'float32') sap_flux_err = array([],'float32') sap_bkg = array([],'float32') sap_bkg_err = array([],'float32') raw_flux = array([],'float32') for i in range(len(time)): work1 = array([],'float64') work2 = array([],'float64') work3 = array([],'float64') work4 = array([],'float64') work5 = array([],'float64') for j in range(len(aperb)): if (aperb[j] == 3): work1 = append(work1,flux[i,j]-sky[i]) work2 = append(work2,flux_err[i,j]) work3 = append(work3,flux_bkg[i,j]) work4 = append(work4,flux_bkg_err[i,j]) work5 = append(work5,raw_cnts[i,j]) sap_flux = append(sap_flux,kepstat.sum(work1)) sap_flux_err = append(sap_flux_err,kepstat.sumerr(work2)) sap_bkg = append(sap_bkg,kepstat.sum(work3)) sap_bkg_err = append(sap_bkg_err,kepstat.sumerr(work4)) raw_flux = append(raw_flux,kepstat.sum(work5)) # construct new table moment data if status == 0: mom_centr1 = zeros(shape=(ntime)) mom_centr2 = zeros(shape=(ntime)) mom_centr1_err = zeros(shape=(ntime)) mom_centr2_err = zeros(shape=(ntime)) for i in range(ntime): xf = zeros(shape=(naper)) yf = zeros(shape=(naper)) f = zeros(shape=(naper)) xfe = zeros(shape=(naper)) yfe = zeros(shape=(naper)) fe = zeros(shape=(naper)) k = -1 for j in range(len(aperb)): if (aperb[j] == 3): k += 1 xf[k] = aperx[j] * flux[i,j] xfe[k] = aperx[j] * flux_err[i,j] yf[k] = apery[j] * flux[i,j] yfe[k] = apery[j] * flux_err[i,j] f[k] = flux[i,j] fe[k] = flux_err[i,j] xfsum = kepstat.sum(xf) yfsum = kepstat.sum(yf) fsum = kepstat.sum(f) xfsume = sqrt(kepstat.sum(square(xfe)) / naper) yfsume = sqrt(kepstat.sum(square(yfe)) / naper) fsume = sqrt(kepstat.sum(square(fe)) / naper) mom_centr1[i] = xfsum / fsum mom_centr2[i] = yfsum / fsum mom_centr1_err[i] = sqrt((xfsume / xfsum)**2 + ((fsume / fsum)**2)) mom_centr2_err[i] = sqrt((yfsume / yfsum)**2 + ((fsume / fsum)**2)) mom_centr1_err = mom_centr1_err * mom_centr1 mom_centr2_err = mom_centr2_err * mom_centr2 # construct new table PSF data if status == 0: psf_centr1 = zeros(shape=(ntime)) psf_centr2 = zeros(shape=(ntime)) psf_centr1_err = zeros(shape=(ntime)) psf_centr2_err = zeros(shape=(ntime)) modx = zeros(shape=(naper)) mody = zeros(shape=(naper)) k = -1 for j in range(len(aperb)): if (aperb[j] == 3): k += 1 modx[k] = aperx[j] mody[k] = apery[j] for i in range(ntime): modf = zeros(shape=(naper)) k = -1 guess = [mom_centr1[i], mom_centr2[i], nanmax(flux[i:]), 1.0, 1.0, 0.0, 0.0] for j in range(len(aperb)): if (aperb[j] == 3): k += 1 modf[k] = flux[i,j] args = (modx, mody, modf) try: ans = leastsq(kepfunc.PRFgauss2d,guess,args=args,xtol=1.0e-8,ftol=1.0e-4,full_output=True) s_sq = (ans[2]['fvec']**2).sum() / (ntime-len(guess)) psf_centr1[i] = ans[0][0] psf_centr2[i] = ans[0][1] except: pass try: psf_centr1_err[i] = sqrt(diag(ans[1] * s_sq))[0] except: psf_centr1_err[i] = numpy.nan try: psf_centr2_err[i] = sqrt(diag(ans[1] * s_sq))[1] except: psf_centr2_err[i] = numpy.nan # construct output primary extension if status == 0: 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 if status == 0: col1 = Column(name='TIME',format='D',unit='BJD - 2454833',array=time) col2 = Column(name='TIMECORR',format='E',unit='d',array=timecorr) col3 = Column(name='CADENCENO',format='J',array=cadenceno) col4 = Column(name='SAP_FLUX',format='E',array=sap_flux) col5 = Column(name='SAP_FLUX_ERR',format='E',array=sap_flux_err) col6 = Column(name='SAP_BKG',format='E',array=sap_bkg) col7 = Column(name='SAP_BKG_ERR',format='E',array=sap_bkg_err) col8 = Column(name='PDCSAP_FLUX',format='E',array=sap_flux) col9 = Column(name='PDCSAP_FLUX_ERR',format='E',array=sap_flux_err) col10 = Column(name='SAP_QUALITY',format='J',array=quality) col11 = Column(name='PSF_CENTR1',format='E',unit='pixel',array=psf_centr1) col12 = Column(name='PSF_CENTR1_ERR',format='E',unit='pixel',array=psf_centr1_err) col13 = Column(name='PSF_CENTR2',format='E',unit='pixel',array=psf_centr2) col14 = Column(name='PSF_CENTR2_ERR',format='E',unit='pixel',array=psf_centr2_err) col15 = Column(name='MOM_CENTR1',format='E',unit='pixel',array=mom_centr1) col16 = Column(name='MOM_CENTR1_ERR',format='E',unit='pixel',array=mom_centr1_err) col17 = Column(name='MOM_CENTR2',format='E',unit='pixel',array=mom_centr2) col18 = Column(name='MOM_CENTR2_ERR',format='E',unit='pixel',array=mom_centr2_err) col19 = Column(name='POS_CORR1',format='E',unit='pixel',array=pos_corr1) col20 = Column(name='POS_CORR2',format='E',unit='pixel',array=pos_corr2) col21 = Column(name='RAW_FLUX',format='E',array=raw_flux) cols = ColDefs([col1,col2,col3,col4,col5,col6,col7,col8,col9,col10,col11, \ col12,col13,col14,col15,col16,col17,col18,col19,col20,col21]) hdu1 = new_table(cols) hdu1.header.update('TTYPE1','TIME','column title: data time stamps') hdu1.header.update('TFORM1','D','data type: float64') hdu1.header.update('TUNIT1','BJD - 2454833','column units: barycenter corrected JD') hdu1.header.update('TDISP1','D12.7','column display format') hdu1.header.update('TTYPE2','TIMECORR','column title: barycentric-timeslice correction') hdu1.header.update('TFORM2','E','data type: float32') hdu1.header.update('TUNIT2','d','column units: days') hdu1.header.update('TTYPE3','CADENCENO','column title: unique cadence number') hdu1.header.update('TFORM3','J','column format: signed integer32') hdu1.header.update('TTYPE4','SAP_FLUX','column title: aperture photometry flux') hdu1.header.update('TFORM4','E','column format: float32') hdu1.header.update('TUNIT4','e-/s','column units: electrons per second') hdu1.header.update('TTYPE5','SAP_FLUX_ERR','column title: aperture phot. flux error') hdu1.header.update('TFORM5','E','column format: float32') hdu1.header.update('TUNIT5','e-/s','column units: electrons per second (1-sigma)') hdu1.header.update('TTYPE6','SAP_BKG','column title: aperture phot. background flux') hdu1.header.update('TFORM6','E','column format: float32') hdu1.header.update('TUNIT6','e-/s','column units: electrons per second') hdu1.header.update('TTYPE7','SAP_BKG_ERR','column title: ap. phot. background flux error') hdu1.header.update('TFORM7','E','column format: float32') hdu1.header.update('TUNIT7','e-/s','column units: electrons per second (1-sigma)') hdu1.header.update('TTYPE8','PDCSAP_FLUX','column title: PDC photometry flux') hdu1.header.update('TFORM8','E','column format: float32') hdu1.header.update('TUNIT8','e-/s','column units: electrons per second') hdu1.header.update('TTYPE9','PDCSAP_FLUX_ERR','column title: PDC flux error') hdu1.header.update('TFORM9','E','column format: float32') hdu1.header.update('TUNIT9','e-/s','column units: electrons per second (1-sigma)') hdu1.header.update('TTYPE10','SAP_QUALITY','column title: aperture photometry quality flag') hdu1.header.update('TFORM10','J','column format: signed integer32') hdu1.header.update('TTYPE11','PSF_CENTR1','column title: PSF fitted column centroid') hdu1.header.update('TFORM11','E','column format: float32') hdu1.header.update('TUNIT11','pixel','column units: pixel') hdu1.header.update('TTYPE12','PSF_CENTR1_ERR','column title: PSF fitted column error') hdu1.header.update('TFORM12','E','column format: float32') hdu1.header.update('TUNIT12','pixel','column units: pixel') hdu1.header.update('TTYPE13','PSF_CENTR2','column title: PSF fitted row centroid') hdu1.header.update('TFORM13','E','column format: float32') hdu1.header.update('TUNIT13','pixel','column units: pixel') hdu1.header.update('TTYPE14','PSF_CENTR2_ERR','column title: PSF fitted row error') hdu1.header.update('TFORM14','E','column format: float32') hdu1.header.update('TUNIT14','pixel','column units: pixel') hdu1.header.update('TTYPE15','MOM_CENTR1','column title: moment-derived column centroid') hdu1.header.update('TFORM15','E','column format: float32') hdu1.header.update('TUNIT15','pixel','column units: pixel') hdu1.header.update('TTYPE16','MOM_CENTR1_ERR','column title: moment-derived column error') hdu1.header.update('TFORM16','E','column format: float32') hdu1.header.update('TUNIT16','pixel','column units: pixel') hdu1.header.update('TTYPE17','MOM_CENTR2','column title: moment-derived row centroid') hdu1.header.update('TFORM17','E','column format: float32') hdu1.header.update('TUNIT17','pixel','column units: pixel') hdu1.header.update('TTYPE18','MOM_CENTR2_ERR','column title: moment-derived row error') hdu1.header.update('TFORM18','E','column format: float32') hdu1.header.update('TUNIT18','pixel','column units: pixel') hdu1.header.update('TTYPE19','POS_CORR1','column title: col correction for vel. abbern') hdu1.header.update('TFORM19','E','column format: float32') hdu1.header.update('TUNIT19','pixel','column units: pixel') hdu1.header.update('TTYPE20','POS_CORR2','column title: row correction for vel. abbern') hdu1.header.update('TFORM20','E','column format: float32') hdu1.header.update('TUNIT20','pixel','column units: pixel') hdu1.header.update('TTYPE21','RAW_FLUX','column title: raw aperture photometry flux') hdu1.header.update('TFORM21','E','column format: float32') hdu1.header.update('TUNIT21','e-/s','column units: electrons per second') hdu1.header.update('EXTNAME','LIGHTCURVE','name of extension') 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 if status == 0: 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 if status == 0: outstr.writeto(outfile,checksum=True) # close input structure if status == 0: status = kepio.closefits(instr,logfile,verbose) # end time kepmsg.clock('KEPEXTRACT finished at',logfile,verbose)
def kepconvert(infile,outfile,conversion,columns,baddata,clobber,verbose,logfile,status): # startup parameters status = 0 # log the call hashline = '----------------------------------------------------------------------------' kepmsg.log(logfile,hashline,verbose) call = 'KEPCONVERT -- ' call += 'infile='+infile+' ' call += 'outfile='+outfile+' ' call += 'conversion='+conversion+' ' call += 'columns='+columns+ ' ' writebad = 'n' if (baddata): writebad = 'y' call += 'baddata='+writebad+ ' ' 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('KEPCONVERT started at',logfile,verbose) # test log file logfile = kepmsg.test(logfile) # data columns if status == 0: colnames = columns.strip().split(',') ncol = len(colnames) if ncol < 1: message = 'ERROR -- KEPCONVERT: no data columns specified' status = kepmsg.err(logfile,message,verbose) # input file exists if status == 0 and not kepio.fileexists(infile): message = 'ERROR -- KEPCONVERT: input file '+infile+' does not exist' status = kepmsg.err(logfile,message,verbose) # clobber output file if status == 0: if clobber: status = kepio.clobber(outfile,logfile,verbose) if kepio.fileexists(outfile): message = 'ERROR -- KEPCONVERT: ' + outfile + ' exists. Use clobber=yes' status = kepmsg.err(logfile,message,verbose) # open FITS input file if status == 0 and conversion == 'fits2asc': instr, status = kepio.openfits(infile,'readonly',logfile,verbose) tstart, tstop, bjdref, cadence, status = kepio.timekeys(instr,infile,logfile,verbose,status) # read FITS table data if status == 0 and conversion == 'fits2asc': table, status = kepio.readfitstab(infile,instr[1],logfile,verbose) # check columns exist in FITS file if not baddata and status == 0 and conversion == 'fits2asc': try: qualcol = table.field('SAP_QUALITY') == 0 except: message = 'No SAP_QUALITY column in data, are you using an old FITS file?' status = kepmsg.err(logfile,message,verbose) if status == 0 and conversion == 'fits2asc': work = [] for colname in colnames: try: if colname.lower() == 'time': work.append(table.field(colname) + bjdref) else: work.append(table.field(colname)) except: message = 'ERROR -- KEPCONVERT: no column ' + colname + ' in ' + infile status = kepmsg.err(logfile,message,verbose) if not baddata: for i in range(len(work)): work[i] = work[i][qualcol] # close input file if status == 0 and conversion == 'fits2asc': status = kepio.closefits(instr,logfile,verbose) ## write output file if status == 0 and conversion == 'fits2asc': # table, status = kepio.openascii(outfile,'w',logfile,verbose) # for i in range(len(work[0])): # txt = '' # for j in range(len(work)): # if numpy.isfinite(work[j][i]): # txt += str(work[j][i]) + ' ' # txt = txt.strip() # if len(re.sub('\s+',',',txt).split(',')) == ncol: # table.write(txt + '\n') # status = kepio.closeascii(table,logfile,verbose) savetxt(outfile,array(work).T) ## open and read ASCII input file if status == 0 and conversion == 'asc2fits': table, status = kepio.openascii(infile,'r',logfile,verbose) ## organize ASCII table into arrays if status == 0 and conversion == 'asc2fits': work = [] for i in range(ncol): work.append([]) nline = 0 for line in table: line = line.strip() line = re.sub('\s+',',',line) line = re.sub('\|',',',line) line = re.sub(';',',',line) if '#' not in line: nline + 1 line = line.split(',') if len(line) == ncol: for i in range(len(line)): try: work[i].append(float(line[i])) except: message = 'ERROR --KEPCONVERT: ' + str(line[i]) + ' is not float' status = kepmsg.err(logfile,message,verbose) break else: message = 'ERROR --KEPCONVERT: ' + str(ncol) + ' columns required but ' message += str(len(line)) + ' columns supplied by ' + infile message += ' at line' + str(nline) status = kepmsg.err(logfile,message,verbose) break for i in range(ncol): work[i] = numpy.array(work[i],dtype='float64') ## timing keywords for output file if status == 0 and conversion == 'asc2fits': for i in range(ncol): if 'time' in colnames[i].lower(): if work[i][1] > 54000.0 and work[i][1] < 60000.0: work[i] += 2.4e6 # work[i] += 2.4553e6 tstart = work[i].min() tstop = work[i].max() lc_start = tstart lc_end = tstop if lc_start > 2.4e6: lc_start -= 2.4e6 if lc_end > 2.4e6: lc_end -= 2.4e6 dts = [] for j in range(1,len(work[i])): dts.append(work[i][j] - work[i][j-1]) dts = numpy.array(dts,dtype='float32') cadence = numpy.median(dts) if cadence * 86400.0 > 58.0 and cadence * 86400.0 < 61.0: obsmode = 'short cadence' elif cadence * 86400.0 > 1600.0 and cadence * 86400.0 < 2000.0: obsmode = 'long cadence' else: obsmode = 'unknown' ## Create the outfile primary extension if status == 0 and conversion == 'asc2fits': hdu0 = PrimaryHDU() try: hdu0.header.update('EXTNAME','PRIMARY','name of extension') hdu0.header.update('EXTVER',1.0,'extension version number') hdu0.header.update('ORIGIN','NASA/Ames','organization that generated this file') hdu0.header.update('DATE',time.asctime(time.localtime()),'file creation date') hdu0.header.update('CREATOR','kepconvert','SW version used to create this file') hdu0.header.update('PROCVER','None','processing script version') hdu0.header.update('FILEVER','2.0','file format version') hdu0.header.update('TIMVERSN','OGIP/93-003','OGIP memo number for file format') hdu0.header.update('TELESCOP','Kepler','telescope') hdu0.header.update('INSTRUME','Kepler photometer','detector type') hdu0.header.update('OBJECT','Unknown','string version of kepID') hdu0.header.update('KEPLERID','Unknown','unique Kepler target identifier') hdu0.header.update('CHANNEL','Unknown','CCD channel') hdu0.header.update('SKYGROUP','Unknown','roll-independent location of channel') hdu0.header.update('MODULE','Unknown','CCD module') hdu0.header.update('OUTPUT','Unknown','CCD output') hdu0.header.update('QUARTER','Unknown','mission quarter during which data was collected') hdu0.header.update('SEASON','Unknown','mission season during which data was collected') hdu0.header.update('DATA_REL','Unknown','version of data release notes describing data') hdu0.header.update('OBSMODE',obsmode,'observing mode') hdu0.header.update('RADESYS','Unknown','reference frame of celestial coordinates') hdu0.header.update('RA_OBJ','Unknown','[deg] right ascension from KIC') hdu0.header.update('DEC_OBJ','Unknown','[deg] declination from KIC') hdu0.header.update('EQUINOX',2000.0,'equinox of celestial coordinate system') hdu0.header.update('PMRA','Unknown','[arcsec/yr] RA proper motion') hdu0.header.update('PMDEC','Unknown','[arcsec/yr] Dec proper motion') hdu0.header.update('PMTOTAL','Unknown','[arcsec/yr] total proper motion') hdu0.header.update('PARALLAX','Unknown','[arcsec] parallax') hdu0.header.update('GLON','Unknown','[deg] galactic longitude') hdu0.header.update('GLAT','Unknown','[deg] galactic latitude') hdu0.header.update('GMAG','Unknown','[mag] SDSS g band magnitude from KIC') hdu0.header.update('RMAG','Unknown','[mag] SDSS r band magnitude from KIC') hdu0.header.update('IMAG','Unknown','[mag] SDSS i band magnitude from KIC') hdu0.header.update('ZMAG','Unknown','[mag] SDSS z band magnitude from KIC') hdu0.header.update('D51MAG','Unknown','[mag] D51 magnitude, from KIC') hdu0.header.update('JMAG','Unknown','[mag] J band magnitude from 2MASS') hdu0.header.update('HMAG','Unknown','[mag] H band magnitude from 2MASS') hdu0.header.update('KMAG','Unknown','[mag] K band magnitude from 2MASS') hdu0.header.update('KEPMAG','Unknown','[mag] Kepler magnitude (Kp) from KIC') hdu0.header.update('GRCOLOR','Unknown','[mag] (g-r) color, SDSS bands') hdu0.header.update('JKCOLOR','Unknown','[mag] (J-K) color, 2MASS bands') hdu0.header.update('GKCOLOR','Unknown','[mag] (g-K) color, SDSS g - 2MASS K') hdu0.header.update('TEFF','Unknown','[K] effective temperature from KIC') hdu0.header.update('LOGG','Unknown','[cm/s2] log10 surface gravity from KIC') hdu0.header.update('FEH','Unknown','[log10([Fe/H])] metallicity from KIC') hdu0.header.update('EBMINUSV','Unknown','[mag] E(B-V) redenning from KIC') hdu0.header.update('AV','Unknown','[mag] A_v extinction from KIC') hdu0.header.update('RADIUS','Unknown','[solar radii] stellar radius from KIC') hdu0.header.update('TMINDEX','Unknown','unique 2MASS catalog ID from KIC') hdu0.header.update('SCPID','Unknown','unique SCP processing ID from KIC') hdulist = HDUList(hdu0) except: message = 'ERROR -- KEPCONVERT: cannot create primary extension in ' + outfile status = kepmsg.err(logfile,message,verbose) ## create the outfile HDU 1 extension if status == 0 and conversion == 'asc2fits': try: fitscol = [] for i in range(ncol): fitscol.append(Column(name=colnames[i],format='D',array=work[i])) fitscols = ColDefs(fitscol) hdu1 = new_table(fitscols) hdulist.append(hdu1) hdu1.header.update('INHERIT',True,'inherit primary keywords') hdu1.header.update('EXTNAME','LIGHTCURVE','name of extension') hdu1.header.update('EXTVER',1,'extension version number') hdu1.header.update('TELESCOP','Kepler','telescope') hdu1.header.update('INSTRUME','Kepler photometer','detector type') hdu1.header.update('OBJECT','Unknown','string version of kepID') hdu1.header.update('KEPLERID','Unknown','unique Kepler target identifier') hdu1.header.update('RADESYS','Unknown','reference frame of celestial coordinates') hdu1.header.update('RA_OBJ','Unknown','[deg] right ascension from KIC') hdu1.header.update('DEC_OBJ','Unknown','[deg] declination from KIC') hdu1.header.update('EQUINOX',2000.0,'equinox of celestial coordinate system') hdu1.header.update('TIMEREF','Unknown','barycentric correction applied to times') hdu1.header.update('TASSIGN','Unknown','where time is assigned') hdu1.header.update('TIMESYS','Unknown','time system is barycentric JD') hdu1.header.update('BJDREFI',0.0,'integer part of BJD reference date') hdu1.header.update('BJDREFF',0.0,'fraction of day in BJD reference date') hdu1.header.update('TIMEUNIT','Unknown','time unit for TIME, TSTART and TSTOP') hdu1.header.update('TSTART',tstart,'observation start time in JD - BJDREF') hdu1.header.update('TSTOP',tstop,'observation stop time in JD - BJDREF') hdu1.header.update('LC_START',lc_start,'observation start time in MJD') hdu1.header.update('LC_END',lc_end,'observation stop time in MJD') hdu1.header.update('TELAPSE',tstop-tstart,'[d] TSTOP - TSTART') hdu1.header.update('LIVETIME','Unknown','[d] TELAPSE multiplied by DEADC') hdu1.header.update('EXPOSURE','Unknown','[d] time on source') hdu1.header.update('DEADC','Unknown','deadtime correction') hdu1.header.update('TIMEPIXR','Unknown','bin time beginning=0 middle=0.5 end=1') hdu1.header.update('TIERRELA','Unknown','[d] relative time error') hdu1.header.update('TIERABSO','Unknown','[d] absolute time error') hdu1.header.update('INT_TIME','Unknown','[s] photon accumulation time per frame') hdu1.header.update('READTIME','Unknown','[s] readout time per frame') hdu1.header.update('FRAMETIM','Unknown','[s] frame time (INT_TIME + READTIME)') hdu1.header.update('NUM_FRM','Unknown','number of frames per time stamp') hdu1.header.update('TIMEDEL','Unknown','[d] time resolution of data') hdu1.header.update('DATE-OBS','Unknown','TSTART as UT calendar date') hdu1.header.update('DATE-END','Unknown','TSTOP as UT calendar date') hdu1.header.update('BACKAPP','Unknown','background is subtracted') hdu1.header.update('DEADAPP','Unknown','deadtime applied') hdu1.header.update('VIGNAPP','Unknown','vignetting or collimator correction applied') hdu1.header.update('GAIN','Unknown','channel gain [electrons/count]') hdu1.header.update('READNOIS','Unknown','read noise [electrons]') hdu1.header.update('NREADOUT','Unknown','number of reads per cadence') hdu1.header.update('TIMSLICE','Unknown','time-slice readout sequence section') hdu1.header.update('MEANBLCK','Unknown','FSW mean black level [count]') hdu1.header.update('PDCSAPFL','Unknown','SAP PDC processing flags (bit code)') hdu1.header.update('PDCDIAFL','Unknown','DIA PDC processing flags (bit code)') hdu1.header.update('MISPXSAP','Unknown','no of optimal aperture pixels missing from SAP') hdu1.header.update('MISPXDIA','Unknown','no of optimal aperture pixels missing from DIA') hdu1.header.update('CROWDSAP','Unknown','crowding metric evaluated over SAP opt. ap.') hdu1.header.update('CROWDDIA','Unknown','crowding metric evaluated over DIA aperture') except: message = 'ERROR -- KEPCONVERT: cannot create light curve extension in ' + outfile status = kepmsg.err(logfile,message,verbose) ## history keyword in output file if status == 0 and conversion == 'asc2fits': status = kepkey.history(call,hdu0,outfile,logfile,verbose) ## filter data table if status == 0 and conversion == 'asc2fits': instr, status = kepio.filterNaN(hdulist,colnames[min(array([1,len(colnames)-1],dtype='int'))], outfile,logfile,verbose) ## write output FITS file if status == 0 and conversion == 'asc2fits': hdulist.writeto(outfile,checksum=True) ## end time if (status == 0): message = 'KEPCONVERT completed at' else: message = '\nKEPCONVERT aborted at' kepmsg.clock(message,logfile,verbose)
def kepffi(ffifile,kepid,ra,dec,aperfile,imin,imax,iscale,cmap,npix, verbose,logfile,status,cmdLine=False): global pimg, zscale, zmin, zmax, xmin, xmax, ymin, ymax, quarter global kepmag, skygroup, season, channel global module, output, row, column, maskfile, plotfile global pkepid, pkepmag, pra, pdec, colmap, mask # input arguments status = 0 seterr(all="ignore") maskfile = 'kepffi-' + str(kepid) + '.txt' plotfile = 'kepffi-' + str(kepid) + '.png' zmin = imin; zmax = imax; zscale = iscale; colmap = cmap # logg the call hashline = '----------------------------------------------------------------------------' kepmsg.log(logfile,hashline,verbose) call = 'KEPFFI -- ' call += 'ffifile='+ffifile+' ' call += 'kepid='+str(kepid)+' ' call += 'ra='+ra+' ' call += 'dec='+dec+' ' call += 'aperfile='+aperfile+' ' call += 'imin='+str(imin)+' ' call += 'imax='+str(imax)+' ' call += 'iscale='+str(iscale)+' ' call += 'cmap'+str(cmap)+' ' call += 'npix='+str(npix)+' ' chatter = 'n' if (verbose): chatter = 'y' call += 'verbose='+chatter+' ' call += 'logfile='+logfile kepmsg.log(logfile,call+'\n',verbose) # start time kepmsg.clock('KEPFFI started at',logfile,verbose) # reference color map if cmap == 'browse': status = cmap_plot(cmdLine) # open existing mask file if kepio.fileexists(aperfile): lines, status = kepio.openascii(aperfile,'r',logfile,verbose) for line in lines: line = line.strip().split('|') y0 = int(line[3]) x0 = int(line[4]) pixels = line[5].split(';') for pixel in pixels: m = y0 + int(pixel.split(',')[0]) n = x0 + int(pixel.split(',')[1]) mask.append(str(m)+','+str(n)) status = kepio.closeascii(lines,logfile,verbose) # RA and Dec conversion if kepid == 'None' or kepid == 'none' or kepid.strip() == '': try: mra = float(ra) mdec = float(dec) except: try: mra,mdec = sex2dec(ra,dec) except: txt = 'ERROR -- no sensible RA and Dec coordinates provided' sys.exit(txt) # open FFI FITS file if status == 0: ffi, status = openfits(ffifile,'readonly') try: quarter = ffi[0].header['QUARTER'] except: try: dateobs = ffi[0].header['DATE-OBS'] if dateobs == '2009-04-24': quarter = 0 if dateobs == '2009-04-25': quarter = 0 if dateobs == '2009-04-26': quarter = 0 if dateobs == '2009-06-19': quarter = 2 if dateobs == '2009-08-19': quarter = 2 if dateobs == '2009-09-17': quarter = 2 if dateobs == '2009-10-19': quarter = 3 if dateobs == '2009-11-18': quarter = 3 if dateobs == '2009-12-17': quarter = 3 except: txt = 'ERROR -- cannot determine quarter when FFI was taken. Either a\n' txt += 'QUARTER or DATE-OBS keyword is expected in the primary header' sys.exit(txt) if quarter == 0: quarter = 1 if quarter < 0: txt = 'ERROR -- cannot determine quarter from FFI. Try downloading a new\n' txt += 'version of KeplerFFI.py from http://keplergo.arc.nasa.gov' sys.exit() if int(quarter) == 0: season = 3 else: season = (int(quarter) - 2) % 4 # locate target in MAST try: int(kepid) kepid,ra,dec,kepmag,skygroup,channel,module,output,row,column \ = MASTKepID(kepid,season) pkepmag = kepmag; pkepid = kepid except: kepid,ra,dec,kepmag,skygroup,channel,module,output,row,column \ = MASTRADec(mra,mdec,8.0,season) ra,dec = dec2sex(ra,dec) pra = ra; pdec = dec print(kepid,ra,dec,kepmag,skygroup,channel,module,output,row,column) # read and close FFI FITS file img, status = readimage(ffi,int(channel)) status = closefits(ffi) # print target data 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(' Column: %4s' % column) print(' Row: %4s' % row) print('') # subimage of channel for plot ymin = int(max([int(row)-npix/2,0])) ymax = int(min([int(row)+npix/2+1,img.shape[0]])) xmin = int(max([int(column)-npix/2,0])) xmax = int(min([int(column)+npix/2+1,img.shape[1]])) # intensity scale nstat = 2; pixels = [] for i in range(ymin,ymax+1): for j in range(xmin,xmax+1): pixels.append(img[i,j]) pixels = array(sort(pixels),dtype=float32) if int(float(len(pixels)) / 10 + 0.5) > nstat: nstat = int(float(len(pixels)) / 10 + 0.5) if not zmin: zmin = median(pixels[:nstat]) if not zmax: zmax = median(pixels[-nstat:]) if 'log' in zscale: img = log10(img) zmin = log10(zmin) zmax = log10(zmax) if ('sq' in zscale): img = sqrt(img) zmin = sqrt(zmin) zmax = sqrt(zmax) pimg = img[ymin:ymax,xmin:xmax] # plot limits ymin = float(ymin) - 0.5 ymax = float(ymax) - 0.5 xmin = float(xmin) - 0.5 xmax = float(xmax) - 0.5 # 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': 16, 'ytick.labelsize': 16} pylab.rcParams.update(params) except: pass if status == 0: pylab.figure(figsize=[10,7]) plotimage(cmdLine) # render plot if cmdLine: pylab.show() else: pylab.ion() pylab.plot([]) pylab.ioff() return
def kepconvert(infile, outfile, conversion, columns, baddata, clobber, verbose, logfile, status): # startup parameters status = 0 # log the call hashline = '----------------------------------------------------------------------------' kepmsg.log(logfile, hashline, verbose) call = 'KEPCONVERT -- ' call += 'infile=' + infile + ' ' call += 'outfile=' + outfile + ' ' call += 'conversion=' + conversion + ' ' call += 'columns=' + columns + ' ' writebad = 'n' if (baddata): writebad = 'y' call += 'baddata=' + writebad + ' ' 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('KEPCONVERT started at', logfile, verbose) # test log file logfile = kepmsg.test(logfile) # data columns if status == 0: colnames = columns.strip().split(',') ncol = len(colnames) if ncol < 1: message = 'ERROR -- KEPCONVERT: no data columns specified' status = kepmsg.err(logfile, message, verbose) # input file exists if status == 0 and not kepio.fileexists(infile): message = 'ERROR -- KEPCONVERT: input file ' + infile + ' does not exist' status = kepmsg.err(logfile, message, verbose) # clobber output file if status == 0: if clobber: status = kepio.clobber(outfile, logfile, verbose) if kepio.fileexists(outfile): message = 'ERROR -- KEPCONVERT: ' + outfile + ' exists. Use clobber=yes' status = kepmsg.err(logfile, message, verbose) # open FITS input file if status == 0 and conversion == 'fits2asc': instr, status = kepio.openfits(infile, 'readonly', logfile, verbose) tstart, tstop, bjdref, cadence, status = kepio.timekeys( instr, infile, logfile, verbose, status) # read FITS table data if status == 0 and conversion == 'fits2asc': table, status = kepio.readfitstab(infile, instr[1], logfile, verbose) # check columns exist in FITS file if not baddata and status == 0 and conversion == 'fits2asc': try: qualcol = table.field('SAP_QUALITY') == 0 except: message = 'No SAP_QUALITY column in data, are you using an old FITS file?' status = kepmsg.err(logfile, message, verbose) if status == 0 and conversion == 'fits2asc': work = [] for colname in colnames: try: if colname.lower() == 'time': work.append(table.field(colname) + bjdref) else: work.append(table.field(colname)) except: message = 'ERROR -- KEPCONVERT: no column ' + colname + ' in ' + infile status = kepmsg.err(logfile, message, verbose) if not baddata: for i in range(len(work)): work[i] = work[i][qualcol] # close input file if status == 0 and conversion == 'fits2asc': status = kepio.closefits(instr, logfile, verbose) ## write output file if status == 0 and conversion == 'fits2asc': # table, status = kepio.openascii(outfile,'w',logfile,verbose) # for i in range(len(work[0])): # txt = '' # for j in range(len(work)): # if numpy.isfinite(work[j][i]): # txt += str(work[j][i]) + ' ' # txt = txt.strip() # if len(re.sub('\s+',',',txt).split(',')) == ncol: # table.write(txt + '\n') # status = kepio.closeascii(table,logfile,verbose) savetxt(outfile, array(work).T) ## open and read ASCII input file if status == 0 and conversion == 'asc2fits': table, status = kepio.openascii(infile, 'r', logfile, verbose) ## organize ASCII table into arrays if status == 0 and conversion == 'asc2fits': work = [] for i in range(ncol): work.append([]) nline = 0 for line in table: line = line.strip() line = re.sub('\s+', ',', line) line = re.sub('\|', ',', line) line = re.sub(';', ',', line) if '#' not in line: nline + 1 line = line.split(',') if len(line) == ncol: for i in range(len(line)): try: work[i].append(float(line[i])) except: message = 'ERROR --KEPCONVERT: ' + str( line[i]) + ' is not float' status = kepmsg.err(logfile, message, verbose) break else: message = 'ERROR --KEPCONVERT: ' + str( ncol) + ' columns required but ' message += str( len(line)) + ' columns supplied by ' + infile message += ' at line' + str(nline) status = kepmsg.err(logfile, message, verbose) break for i in range(ncol): work[i] = numpy.array(work[i], dtype='float64') ## timing keywords for output file if status == 0 and conversion == 'asc2fits': for i in range(ncol): if 'time' in colnames[i].lower(): if work[i][1] > 54000.0 and work[i][1] < 60000.0: work[i] += 2.4e6 # work[i] += 2.4553e6 tstart = work[i].min() tstop = work[i].max() lc_start = tstart lc_end = tstop if lc_start > 2.4e6: lc_start -= 2.4e6 if lc_end > 2.4e6: lc_end -= 2.4e6 dts = [] for j in range(1, len(work[i])): dts.append(work[i][j] - work[i][j - 1]) dts = numpy.array(dts, dtype='float32') cadence = numpy.median(dts) if cadence * 86400.0 > 58.0 and cadence * 86400.0 < 61.0: obsmode = 'short cadence' elif cadence * 86400.0 > 1600.0 and cadence * 86400.0 < 2000.0: obsmode = 'long cadence' else: obsmode = 'unknown' ## Create the outfile primary extension if status == 0 and conversion == 'asc2fits': hdu0 = PrimaryHDU() try: hdu0.header.update('EXTNAME', 'PRIMARY', 'name of extension') hdu0.header.update('EXTVER', 1.0, 'extension version number') hdu0.header.update('ORIGIN', 'NASA/Ames', 'organization that generated this file') hdu0.header.update('DATE', time.asctime(time.localtime()), 'file creation date') hdu0.header.update('CREATOR', 'kepconvert', 'SW version used to create this file') hdu0.header.update('PROCVER', 'None', 'processing script version') hdu0.header.update('FILEVER', '2.0', 'file format version') hdu0.header.update('TIMVERSN', 'OGIP/93-003', 'OGIP memo number for file format') hdu0.header.update('TELESCOP', 'Kepler', 'telescope') hdu0.header.update('INSTRUME', 'Kepler photometer', 'detector type') hdu0.header.update('OBJECT', 'Unknown', 'string version of kepID') hdu0.header.update('KEPLERID', 'Unknown', 'unique Kepler target identifier') hdu0.header.update('CHANNEL', 'Unknown', 'CCD channel') hdu0.header.update('SKYGROUP', 'Unknown', 'roll-independent location of channel') hdu0.header.update('MODULE', 'Unknown', 'CCD module') hdu0.header.update('OUTPUT', 'Unknown', 'CCD output') hdu0.header.update( 'QUARTER', 'Unknown', 'mission quarter during which data was collected') hdu0.header.update( 'SEASON', 'Unknown', 'mission season during which data was collected') hdu0.header.update( 'DATA_REL', 'Unknown', 'version of data release notes describing data') hdu0.header.update('OBSMODE', obsmode, 'observing mode') hdu0.header.update('RADESYS', 'Unknown', 'reference frame of celestial coordinates') hdu0.header.update('RA_OBJ', 'Unknown', '[deg] right ascension from KIC') hdu0.header.update('DEC_OBJ', 'Unknown', '[deg] declination from KIC') hdu0.header.update('EQUINOX', 2000.0, 'equinox of celestial coordinate system') hdu0.header.update('PMRA', 'Unknown', '[arcsec/yr] RA proper motion') hdu0.header.update('PMDEC', 'Unknown', '[arcsec/yr] Dec proper motion') hdu0.header.update('PMTOTAL', 'Unknown', '[arcsec/yr] total proper motion') hdu0.header.update('PARALLAX', 'Unknown', '[arcsec] parallax') hdu0.header.update('GLON', 'Unknown', '[deg] galactic longitude') hdu0.header.update('GLAT', 'Unknown', '[deg] galactic latitude') hdu0.header.update('GMAG', 'Unknown', '[mag] SDSS g band magnitude from KIC') hdu0.header.update('RMAG', 'Unknown', '[mag] SDSS r band magnitude from KIC') hdu0.header.update('IMAG', 'Unknown', '[mag] SDSS i band magnitude from KIC') hdu0.header.update('ZMAG', 'Unknown', '[mag] SDSS z band magnitude from KIC') hdu0.header.update('D51MAG', 'Unknown', '[mag] D51 magnitude, from KIC') hdu0.header.update('JMAG', 'Unknown', '[mag] J band magnitude from 2MASS') hdu0.header.update('HMAG', 'Unknown', '[mag] H band magnitude from 2MASS') hdu0.header.update('KMAG', 'Unknown', '[mag] K band magnitude from 2MASS') hdu0.header.update('KEPMAG', 'Unknown', '[mag] Kepler magnitude (Kp) from KIC') hdu0.header.update('GRCOLOR', 'Unknown', '[mag] (g-r) color, SDSS bands') hdu0.header.update('JKCOLOR', 'Unknown', '[mag] (J-K) color, 2MASS bands') hdu0.header.update('GKCOLOR', 'Unknown', '[mag] (g-K) color, SDSS g - 2MASS K') hdu0.header.update('TEFF', 'Unknown', '[K] effective temperature from KIC') hdu0.header.update('LOGG', 'Unknown', '[cm/s2] log10 surface gravity from KIC') hdu0.header.update('FEH', 'Unknown', '[log10([Fe/H])] metallicity from KIC') hdu0.header.update('EBMINUSV', 'Unknown', '[mag] E(B-V) redenning from KIC') hdu0.header.update('AV', 'Unknown', '[mag] A_v extinction from KIC') hdu0.header.update('RADIUS', 'Unknown', '[solar radii] stellar radius from KIC') hdu0.header.update('TMINDEX', 'Unknown', 'unique 2MASS catalog ID from KIC') hdu0.header.update('SCPID', 'Unknown', 'unique SCP processing ID from KIC') hdulist = HDUList(hdu0) except: message = 'ERROR -- KEPCONVERT: cannot create primary extension in ' + outfile status = kepmsg.err(logfile, message, verbose) ## create the outfile HDU 1 extension if status == 0 and conversion == 'asc2fits': try: fitscol = [] for i in range(ncol): fitscol.append( Column(name=colnames[i], format='D', array=work[i])) fitscols = ColDefs(fitscol) hdu1 = new_table(fitscols) hdulist.append(hdu1) hdu1.header.update('INHERIT', True, 'inherit primary keywords') hdu1.header.update('EXTNAME', 'LIGHTCURVE', 'name of extension') hdu1.header.update('EXTVER', 1, 'extension version number') hdu1.header.update('TELESCOP', 'Kepler', 'telescope') hdu1.header.update('INSTRUME', 'Kepler photometer', 'detector type') hdu1.header.update('OBJECT', 'Unknown', 'string version of kepID') hdu1.header.update('KEPLERID', 'Unknown', 'unique Kepler target identifier') hdu1.header.update('RADESYS', 'Unknown', 'reference frame of celestial coordinates') hdu1.header.update('RA_OBJ', 'Unknown', '[deg] right ascension from KIC') hdu1.header.update('DEC_OBJ', 'Unknown', '[deg] declination from KIC') hdu1.header.update('EQUINOX', 2000.0, 'equinox of celestial coordinate system') hdu1.header.update('TIMEREF', 'Unknown', 'barycentric correction applied to times') hdu1.header.update('TASSIGN', 'Unknown', 'where time is assigned') hdu1.header.update('TIMESYS', 'Unknown', 'time system is barycentric JD') hdu1.header.update('BJDREFI', 0.0, 'integer part of BJD reference date') hdu1.header.update('BJDREFF', 0.0, 'fraction of day in BJD reference date') hdu1.header.update('TIMEUNIT', 'Unknown', 'time unit for TIME, TSTART and TSTOP') hdu1.header.update('TSTART', tstart, 'observation start time in JD - BJDREF') hdu1.header.update('TSTOP', tstop, 'observation stop time in JD - BJDREF') hdu1.header.update('LC_START', lc_start, 'observation start time in MJD') hdu1.header.update('LC_END', lc_end, 'observation stop time in MJD') hdu1.header.update('TELAPSE', tstop - tstart, '[d] TSTOP - TSTART') hdu1.header.update('LIVETIME', 'Unknown', '[d] TELAPSE multiplied by DEADC') hdu1.header.update('EXPOSURE', 'Unknown', '[d] time on source') hdu1.header.update('DEADC', 'Unknown', 'deadtime correction') hdu1.header.update('TIMEPIXR', 'Unknown', 'bin time beginning=0 middle=0.5 end=1') hdu1.header.update('TIERRELA', 'Unknown', '[d] relative time error') hdu1.header.update('TIERABSO', 'Unknown', '[d] absolute time error') hdu1.header.update('INT_TIME', 'Unknown', '[s] photon accumulation time per frame') hdu1.header.update('READTIME', 'Unknown', '[s] readout time per frame') hdu1.header.update('FRAMETIM', 'Unknown', '[s] frame time (INT_TIME + READTIME)') hdu1.header.update('NUM_FRM', 'Unknown', 'number of frames per time stamp') hdu1.header.update('TIMEDEL', 'Unknown', '[d] time resolution of data') hdu1.header.update('DATE-OBS', 'Unknown', 'TSTART as UT calendar date') hdu1.header.update('DATE-END', 'Unknown', 'TSTOP as UT calendar date') hdu1.header.update('BACKAPP', 'Unknown', 'background is subtracted') hdu1.header.update('DEADAPP', 'Unknown', 'deadtime applied') hdu1.header.update('VIGNAPP', 'Unknown', 'vignetting or collimator correction applied') hdu1.header.update('GAIN', 'Unknown', 'channel gain [electrons/count]') hdu1.header.update('READNOIS', 'Unknown', 'read noise [electrons]') hdu1.header.update('NREADOUT', 'Unknown', 'number of reads per cadence') hdu1.header.update('TIMSLICE', 'Unknown', 'time-slice readout sequence section') hdu1.header.update('MEANBLCK', 'Unknown', 'FSW mean black level [count]') hdu1.header.update('PDCSAPFL', 'Unknown', 'SAP PDC processing flags (bit code)') hdu1.header.update('PDCDIAFL', 'Unknown', 'DIA PDC processing flags (bit code)') hdu1.header.update( 'MISPXSAP', 'Unknown', 'no of optimal aperture pixels missing from SAP') hdu1.header.update( 'MISPXDIA', 'Unknown', 'no of optimal aperture pixels missing from DIA') hdu1.header.update('CROWDSAP', 'Unknown', 'crowding metric evaluated over SAP opt. ap.') hdu1.header.update('CROWDDIA', 'Unknown', 'crowding metric evaluated over DIA aperture') except: message = 'ERROR -- KEPCONVERT: cannot create light curve extension in ' + outfile status = kepmsg.err(logfile, message, verbose) ## history keyword in output file if status == 0 and conversion == 'asc2fits': status = kepkey.history(call, hdu0, outfile, logfile, verbose) ## filter data table if status == 0 and conversion == 'asc2fits': instr, status = kepio.filterNaN( hdulist, colnames[min(array([1, len(colnames) - 1], dtype='int'))], outfile, logfile, verbose) ## write output FITS file if status == 0 and conversion == 'asc2fits': hdulist.writeto(outfile, checksum=True) ## end time if (status == 0): message = 'KEPCONVERT completed at' else: message = '\nKEPCONVERT aborted at' kepmsg.clock(message, logfile, verbose)