Esempio n. 1
0
def kepprf(infile,plotfile,rownum,columns,rows,fluxes,border,background,focus,prfdir,xtol,ftol,
           imscale,colmap,labcol,apercol,plt,verbose,logfile,status,cmdLine=False): 

# input arguments

    status = 0
    seterr(all="ignore") 

# log the call 

    hashline = '----------------------------------------------------------------------------'
    kepmsg.log(logfile,hashline,verbose)
    call = 'KEPPRF -- '
    call += 'infile='+infile+' '
    call += 'plotfile='+plotfile+' '
    call += 'rownum='+str(rownum)+' '
    call += 'columns='+columns+' '
    call += 'rows='+rows+' '
    call += 'fluxes='+fluxes+' '
    call += 'border='+str(border)+' '
    bground = 'n'
    if (background): bground = 'y'
    call += 'background='+bground+' '
    focs = 'n'
    if (focus): focs = 'y'
    call += 'focus='+focs+' '
    call += 'prfdir='+prfdir+' '
    call += 'xtol='+str(xtol)+' '
    call += 'ftol='+str(xtol)+' '
    call += 'imscale='+imscale+' '
    call += 'colmap='+colmap+' '
    call += 'labcol='+labcol+' '
    call += 'apercol='+apercol+' '
    plotit = 'n'
    if (plt): plotit = 'y'
    call += 'plot='+plotit+' '
    chatter = 'n'
    if (verbose): chatter = 'y'
    call += 'verbose='+chatter+' '
    call += 'logfile='+logfile
    kepmsg.log(logfile,call+'\n',verbose)

# test log file

    logfile = kepmsg.test(logfile)

# start time

    kepmsg.clock('KEPPRF started at',logfile,verbose)

# reference color map

    if colmap == 'browse':
        status = cmap_plot(cmdLine)

# construct inital guess vector for fit 

    if status == 0:
        guess = []
        try:
            f = fluxes.strip().split(',')
            x = columns.strip().split(',')
            y = rows.strip().split(',')
            for i in xrange(len(f)):
                f[i] = float(f[i])
        except:
            f = fluxes
            x = columns
            y = rows
        nsrc = len(f)
        for i in xrange(nsrc):
            try:
                guess.append(float(f[i]))
            except:
                message = 'ERROR -- KEPPRF: Fluxes must be floating point numbers'
                status = kepmsg.err(logfile,message,verbose)
        if status == 0:
            if len(x) != nsrc or len(y) != nsrc:
                message = 'ERROR -- KEPFIT:FITMULTIPRF: Guesses for rows, columns and '
                message += 'fluxes must have the same number of sources'
                status = kepmsg.err(logfile,message,verbose)
        if status == 0:
            for i in xrange(nsrc):
                try:
                    guess.append(float(x[i]))
                except:
                    message = 'ERROR -- KEPPRF: Columns must be floating point numbers'
                    status = kepmsg.err(logfile,message,verbose)
        if status == 0:
            for i in xrange(nsrc):
                try:
                    guess.append(float(y[i]))
                except:
                    message = 'ERROR -- KEPPRF: Rows must be floating point numbers'
                    status = kepmsg.err(logfile,message,verbose)
        if status == 0 and background:
            if border == 0:
                guess.append(0.0)
            else:
                for i in range((border+1)*2):
                    guess.append(0.0)
        if status == 0 and focus:
            guess.append(1.0); guess.append(1.0); guess.append(0.0)

# open TPF FITS file

    if status == 0:
        try:
            kepid, channel, skygroup, module, output, quarter, season, \
                ra, dec, column, row, kepmag, xdim, ydim, barytime, status = \
                kepio.readTPF(infile,'TIME',logfile,verbose)
        except:
            message = 'ERROR -- KEPPRF: is %s a Target Pixel File? ' % infile
            status = kepmsg.err(logfile,message,verbose)
    if status == 0:
        kepid, channel, skygroup, module, output, quarter, season, \
            ra, dec, column, row, kepmag, xdim, ydim, tcorr, status = \
            kepio.readTPF(infile,'TIMECORR',logfile,verbose)
    if status == 0:
        kepid, channel, skygroup, module, output, quarter, season, \
            ra, dec, column, row, kepmag, xdim, ydim, cadno, status = \
            kepio.readTPF(infile,'CADENCENO',logfile,verbose)
    if status == 0:
        kepid, channel, skygroup, module, output, quarter, season, \
            ra, dec, column, row, kepmag, xdim, ydim, fluxpixels, status = \
            kepio.readTPF(infile,'FLUX',logfile,verbose)
    if status == 0:
        kepid, channel, skygroup, module, output, quarter, season, \
            ra, dec, column, row, kepmag, xdim, ydim, errpixels, status = \
            kepio.readTPF(infile,'FLUX_ERR',logfile,verbose)
    if status == 0:
        kepid, channel, skygroup, module, output, quarter, season, \
            ra, dec, column, row, kepmag, xdim, ydim, qual, status = \
            kepio.readTPF(infile,'QUALITY',logfile,verbose)

# read mask defintion data from TPF file

    if status == 0:
        maskimg, pixcoord1, pixcoord2, status = kepio.readMaskDefinition(infile,logfile,verbose)
        npix = numpy.size(numpy.nonzero(maskimg)[0])

# print target data

    if status == 0 and verbose:
        print ''
        print '      KepID: %s' % kepid
        print '        BJD: %.2f' % (barytime[rownum-1] + 2454833.0)
        print ' RA (J2000): %s' % ra
        print 'Dec (J2000):  %s' % dec
        print '     KepMag:  %s' % kepmag
        print '   SkyGroup:   %2s' % skygroup
        print '     Season:   %2s' % str(season)
        print '    Channel:   %2s' % channel
        print '     Module:   %2s' % module
        print '     Output:    %1s' % output
        print ''

# is this a good row with finite timestamp and pixels?

    if status == 0:
        if not numpy.isfinite(barytime[rownum-1]) or numpy.nansum(fluxpixels[rownum-1,:]) == numpy.nan:
            message = 'ERROR -- KEPFIELD: Row ' + str(rownum) + ' is a bad quality timestamp'
            status = kepmsg.err(logfile,message,verbose)

# construct input pixel image

    if status == 0:
        flux = fluxpixels[rownum-1,:]
        ferr = errpixels[rownum-1,:]
        DATx = arange(column,column+xdim)
        DATy = arange(row,row+ydim)
#        if numpy.nanmin > 420000.0: flux -= 420000.0

# image scale and intensity limits of pixel data

    if status == 0:
        n = 0
        DATimg = empty((ydim,xdim))
        ERRimg = empty((ydim,xdim))
        for i in range(ydim):
            for j in range(xdim):
                DATimg[i,j] = flux[n]
                ERRimg[i,j] = ferr[n]
                n += 1

# determine suitable PRF calibration file

    if status == 0:
        if int(module) < 10:
            prefix = 'kplr0'
        else:
            prefix = 'kplr'
        prfglob = prfdir + '/' + prefix + str(module) + '.' + str(output) + '*' + '_prf.fits'
        try:
            prffile = glob.glob(prfglob)[0]
        except:
            message = 'ERROR -- KEPPRF: No PRF file found in ' + prfdir
            status = kepmsg.err(logfile,message,verbose)

# read PRF images

    if status == 0:
        prfn = [0,0,0,0,0]
        crpix1p = numpy.zeros((5),dtype='float32')
        crpix2p = numpy.zeros((5),dtype='float32')
        crval1p = numpy.zeros((5),dtype='float32')
        crval2p = numpy.zeros((5),dtype='float32')
        cdelt1p = numpy.zeros((5),dtype='float32')
        cdelt2p = numpy.zeros((5),dtype='float32')
        for i in range(5):
            prfn[i], crpix1p[i], crpix2p[i], crval1p[i], crval2p[i], cdelt1p[i], cdelt2p[i], status \
                = kepio.readPRFimage(prffile,i+1,logfile,verbose) 
        prfn = array(prfn)
        PRFx = arange(0.5,shape(prfn[0])[1]+0.5)
        PRFy = arange(0.5,shape(prfn[0])[0]+0.5)
        PRFx = (PRFx - size(PRFx) / 2) * cdelt1p[0]
        PRFy = (PRFy - size(PRFy) / 2) * cdelt2p[0]

# interpolate the calibrated PRF shape to the target position

    if status == 0:
        prf = zeros(shape(prfn[0]),dtype='float32')
        prfWeight = zeros((5),dtype='float32')
        for i in xrange(5):
            prfWeight[i] = sqrt((column - crval1p[i])**2 + (row - crval2p[i])**2)
            if prfWeight[i] == 0.0:
                prfWeight[i] = 1.0e-6
            prf = prf + prfn[i] / prfWeight[i]
        prf = prf / nansum(prf) / cdelt1p[0] / cdelt2p[0]

# interpolate the calibrated PRF shape to the target position

#    if status == 0:
#        prf = zeros(shape(prfn[0,:,:]),dtype='float32')
#        px = crval1p + len(PRFx) / 2 * cdelt1p[0]
#        py = crval2p + len(PRFy) / 2 * cdelt2p[0]
#        pp = [[px[0],py[0]],
#              [px[1],py[1]],
#              [px[2],py[2]],
#              [px[3],py[3]],
#              [px[4],py[4]]]
#        for index,value in ndenumerate(prf):
#            pz = prfn[:,index[0],index[1]]
#            prf[index] = griddata(pp, pz, ([column], [row]), method='linear')
#        print shape(prf)

# location of the data image centered on the PRF image (in PRF pixel units)

    if status == 0:
        prfDimY = int(ydim / cdelt1p[0])
        prfDimX = int(xdim / cdelt2p[0])
        PRFy0 = (shape(prf)[0] - prfDimY) / 2
        PRFx0 = (shape(prf)[1] - prfDimX) / 2

# interpolation function over the PRF

    if status == 0:
        splineInterpolation = scipy.interpolate.RectBivariateSpline(PRFx,PRFy,prf)

# construct mesh for background model

    if status == 0 and background:
        bx = numpy.arange(1.,float(xdim+1))
        by = numpy.arange(1.,float(ydim+1))
        xx, yy = numpy.meshgrid(numpy.linspace(bx.min(), bx.max(), xdim),
                                numpy.linspace(by.min(), by.max(), ydim))

# fit PRF model to pixel data

    if status == 0:
        start = time.time()
        if focus and background:
            args = (DATx,DATy,DATimg,ERRimg,nsrc,border,xx,yy,splineInterpolation,float(x[0]),float(y[0]))
            ans = fmin_powell(kepfunc.PRFwithFocusAndBackground,guess,args=args,xtol=xtol,
                              ftol=ftol,disp=False)
        elif focus and not background:
            args = (DATx,DATy,DATimg,ERRimg,nsrc,splineInterpolation,float(x[0]),float(y[0]))
            ans = fmin_powell(kepfunc.PRFwithFocus,guess,args=args,xtol=xtol,
                              ftol=ftol,disp=False)                    
        elif background and not focus:
            args = (DATx,DATy,DATimg,ERRimg,nsrc,border,xx,yy,splineInterpolation,float(x[0]),float(y[0]))
            ans = fmin_powell(kepfunc.PRFwithBackground,guess,args=args,xtol=xtol,
                              ftol=ftol,disp=False)
        else:
            args = (DATx,DATy,DATimg,ERRimg,nsrc,splineInterpolation,float(x[0]),float(y[0]))
            ans = fmin_powell(kepfunc.PRF,guess,args=args,xtol=xtol,
                              ftol=ftol,disp=False)
        print 'Convergence time = %.2fs\n' % (time.time() - start)

# pad the PRF data if the PRF array is smaller than the data array 

    if status == 0:
        flux = []; OBJx = []; OBJy = []
        PRFmod = numpy.zeros((prfDimY,prfDimX))
        if PRFy0 < 0 or PRFx0 < 0.0:
            PRFmod = numpy.zeros((prfDimY,prfDimX))
            superPRF = zeros((prfDimY+1,prfDimX+1))
            superPRF[abs(PRFy0):abs(PRFy0)+shape(prf)[0],abs(PRFx0):abs(PRFx0)+shape(prf)[1]] = prf
            prf = superPRF * 1.0
            PRFy0 = 0
            PRFx0 = 0

# rotate the PRF model around its center

        if focus:
            angle = ans[-1]
            prf = rotate(prf,-angle,reshape=False,mode='nearest')

# iterate through the sources in the best fit PSF model

        for i in range(nsrc):
            flux.append(ans[i])
            OBJx.append(ans[nsrc+i])
            OBJy.append(ans[nsrc*2+i]) 

# calculate best-fit model

            y = (OBJy[i]-mean(DATy)) / cdelt1p[0]
            x = (OBJx[i]-mean(DATx)) / cdelt2p[0]
            prfTmp = shift(prf,[y,x],order=3,mode='constant')
            prfTmp = prfTmp[PRFy0:PRFy0+prfDimY,PRFx0:PRFx0+prfDimX]
            PRFmod = PRFmod + prfTmp * flux[i]
            wx = 1.0
            wy = 1.0
            angle = 0
            b = 0.0

# write out best fit parameters

            if verbose:
                txt = 'Flux = %10.2f e-/s ' % flux[i]
                txt += 'X = %9.4f pix ' % OBJx[i]
                txt += 'Y = %9.4f pix ' % OBJy[i]
                kepmsg.log(logfile,txt,True)
#
#        params = {'backend': 'png',
#                  'axes.linewidth': 2.5,
#                  'axes.labelsize': 24,
#                  'axes.font': 'sans-serif',
#                  'axes.fontweight' : 'bold',
#                  'text.fontsize': 12,
#                  'legend.fontsize': 12,
#                  'xtick.labelsize': 24,
#                  'ytick.labelsize': 24}
#        pylab.rcParams.update(params)
#
#        pylab.figure(figsize=[20,10])
#        ax = pylab.axes([0.05,0.08,0.46,0.9])
#        xxx = numpy.arange(397.5,402.5,0.02)
#        yyy = numpy.sum(PRFmod,axis=0) / numpy.max(numpy.sum(PRFmod,axis=0))
#        pylab.plot(xxx,yyy,color='b',linewidth=3.0) 
#        xxx = numpy.append(numpy.insert(xxx,[0],[xxx[0]]),xxx[-1])
#        yyy = numpy.append(numpy.insert(yyy,[0],[0.0]),yyy[-1]) 
#        pylab.fill(xxx,yyy,fc='y',linewidth=0.0,alpha=0.3) 
#        pylab.xlabel('Pixel Column Number')
#        pylab.xlim(397.5,402.5)
#        pylab.ylim(1.0e-30,1.02)
#        for xmaj in numpy.arange(397.5,402.5,1.0):
#            pylab.plot([xmaj,xmaj],[0.0,1.1],color='k',linewidth=0.5,linestyle=':') 
#        for xmaj in numpy.arange(0.2,1.2,0.2):
#            pylab.plot([0.0,2000.0],[xmaj,xmaj],color='k',linewidth=0.5,linestyle=':') 
#            
#
#        ax = pylab.axes([0.51,0.08,0.46,0.9])
#        xxx = numpy.arange(32.5,37.5,0.02)
#        yyy = numpy.sum(PRFmod,axis=1) / numpy.max(numpy.sum(PRFmod,axis=1))
#        pylab.plot(xxx,yyy,color='b',linewidth=3.0) 
#        xxx = numpy.append(numpy.insert(xxx,[0],[xxx[0]]),xxx[-1])
#        yyy = numpy.append(numpy.insert(yyy,[0],[0.0]),yyy[-1]) 
#        pylab.fill(xxx,yyy,fc='y',linewidth=0.0,alpha=0.3) 
#        pylab.setp(pylab.gca(),yticklabels=[])
#        pylab.xlabel('Pixel Row Number')
#        pylab.xlim(32.5,37.5)
#        pylab.ylim(1.0e-30,1.02)
#        for xmaj in numpy.arange(32.5,37.5,1.0):
#            pylab.plot([xmaj,xmaj],[0.0,1.1],color='k',linewidth=0.5,linestyle=':') 
#        for xmaj in numpy.arange(0.2,1.2,0.2):
#            pylab.plot([0.0,2000.0],[xmaj,xmaj],color='k',linewidth=0.5,linestyle=':') 
#        pylab.ion()
#        pylab.plot([])
#        pylab.ioff()

        if verbose and background:
            bterms = border + 1
            if bterms == 1:
                b = ans[nsrc*3]
            else:
                bcoeff = array([ans[nsrc*3:nsrc*3+bterms],ans[nsrc*3+bterms:nsrc*3+bterms*2]]) 
                bkg = kepfunc.polyval2d(xx,yy,bcoeff)
                b = nanmean(bkg.reshape(bkg.size))
            txt = '\n   Mean background = %.2f e-/s' % b
            kepmsg.log(logfile,txt,True)
        if focus:
            wx = ans[-3]
            wy = ans[-2]
            angle = ans[-1]
        if verbose and focus:
            if not background: kepmsg.log(logfile,'',True)
            kepmsg.log(logfile,' X/Y focus factors = %.3f/%.3f' % (wx,wy),True)
            kepmsg.log(logfile,'PRF rotation angle = %.2f deg' % angle,True)

# measure flux fraction and contamination

    if status == 0:
        PRFall = kepfunc.PRF2DET(flux,OBJx,OBJy,DATx,DATy,wx,wy,angle,splineInterpolation)
        PRFone = kepfunc.PRF2DET([flux[0]],[OBJx[0]],[OBJy[0]],DATx,DATy,wx,wy,angle,splineInterpolation)
        FluxInMaskAll = numpy.nansum(PRFall)
        FluxInMaskOne = numpy.nansum(PRFone)
        FluxInAperAll = 0.0
        FluxInAperOne = 0.0
        for i in range(1,ydim):
            for j in range(1,xdim):
                if kepstat.bitInBitmap(maskimg[i,j],2):
                    FluxInAperAll += PRFall[i,j]
                    FluxInAperOne += PRFone[i,j]
        FluxFraction = FluxInAperOne / flux[0]
        try:
            Contamination = (FluxInAperAll - FluxInAperOne) / FluxInAperAll
        except:
            Contamination = 0.0

        kepmsg.log(logfile,'\n                Total flux in mask = %.2f e-/s' % FluxInMaskAll,True)
        kepmsg.log(logfile,'               Target flux in mask = %.2f e-/s' % FluxInMaskOne,True)
        kepmsg.log(logfile,'            Total flux in aperture = %.2f e-/s' % FluxInAperAll,True)
        kepmsg.log(logfile,'           Target flux in aperture = %.2f e-/s' % FluxInAperOne,True)
        kepmsg.log(logfile,'  Target flux fraction in aperture = %.2f%%' % (FluxFraction * 100.0),True)
        kepmsg.log(logfile,'Contamination fraction in aperture = %.2f%%' % (Contamination * 100.0),True)


# constuct model PRF in detector coordinates

    if status == 0:
        PRFfit = PRFall + 0.0
        if background and bterms == 1:
            PRFfit = PRFall + b
        if background and bterms > 1:
            PRFfit = PRFall + bkg

# calculate residual of DATA - FIT

    if status == 0:
        PRFres = DATimg - PRFfit
        FLUXres = numpy.nansum(PRFres) / npix
    
# calculate the sum squared difference between data and model

    if status == 0:
        Pearson = abs(numpy.nansum(numpy.square(DATimg - PRFfit) / PRFfit))
        Chi2 = numpy.nansum(numpy.square(DATimg - PRFfit) / numpy.square(ERRimg))
        DegOfFreedom = npix - len(guess) - 1
        try:
            kepmsg.log(logfile,'\n       Residual flux = %.2f e-/s' % FLUXres,True)
            kepmsg.log(logfile,'Pearson\'s chi^2 test = %d for %d dof' % (Pearson,DegOfFreedom),True)
        except:
            pass
        kepmsg.log(logfile,'          Chi^2 test = %d for %d dof' % (Chi2,DegOfFreedom),True)

# image scale and intensity limits for plotting images

    if status == 0:
        imgdat_pl, zminfl, zmaxfl = kepplot.intScale2D(DATimg,imscale)
        imgprf_pl, zminpr, zmaxpr = kepplot.intScale2D(PRFmod,imscale)
        imgfit_pl, zminfi, zmaxfi = kepplot.intScale2D(PRFfit,imscale)
        imgres_pl, zminre, zmaxre = kepplot.intScale2D(PRFres,'linear')
        if imscale == 'linear':
            zmaxpr *= 0.9
        elif imscale == 'logarithmic':
            zmaxpr = numpy.max(zmaxpr)
            zminpr = zmaxpr / 2
        
# plot style

    if status == 0:
        try:
            params = {'backend': 'png',
                      'axes.linewidth': 2.5,
                      'axes.labelsize': 28,
                      'axes.font': 'sans-serif',
                      'axes.fontweight' : 'bold',
                      'text.fontsize': 12,
                      'legend.fontsize': 12,
                      'xtick.labelsize': 20,
                      'ytick.labelsize': 20,
                      'xtick.major.pad': 6,
                      'ytick.major.pad': 6}
            pylab.rcParams.update(params)
        except:
            pass
        pylab.figure(figsize=[12,10])
        pylab.clf()
        plotimage(imgdat_pl,zminfl,zmaxfl,1,row,column,xdim,ydim,0.07,0.53,'observation',colmap,labcol)
#        pylab.text(830.0,242.1,'A',horizontalalignment='center',verticalalignment='center',
#                   fontsize=28,fontweight=500,color='white')
#        pylab.text(831.1,240.62,'B',horizontalalignment='center',verticalalignment='center',
#                   fontsize=28,fontweight=500,color='white')
#        plotimage(imgprf_pl,0.0,zmaxpr/0.5,2,row,column,xdim,ydim,0.52,0.52,'model',colmap)
        plotimage(imgprf_pl,zminpr,zmaxpr,2,row,column,xdim,ydim,0.44,0.53,'model',colmap,labcol)
        kepplot.borders(maskimg,xdim,ydim,pixcoord1,pixcoord2,1,apercol,'--',0.5)
        kepplot.borders(maskimg,xdim,ydim,pixcoord1,pixcoord2,2,apercol,'-',3.0)
        plotimage(imgfit_pl,zminfl,zmaxfl,3,row,column,xdim,ydim,0.07,0.08,'fit',colmap,labcol)
#        plotimage(imgres_pl,-zmaxre,zmaxre,4,row,column,xdim,ydim,0.44,0.08,'residual',colmap,'k')
        plotimage(imgres_pl,zminfl,zmaxfl,4,row,column,xdim,ydim,0.44,0.08,'residual',colmap,labcol)
            
# plot data color bar

#    barwin = pylab.axes([0.84,0.53,0.06,0.45])
    barwin = pylab.axes([0.84,0.08,0.06,0.9])
    if imscale == 'linear':
        brange = numpy.arange(zminfl,zmaxfl,(zmaxfl-zminfl)/1000)
    elif imscale == 'logarithmic':
        brange = numpy.arange(10.0**zminfl,10.0**zmaxfl,(10.0**zmaxfl-10.0**zminfl)/1000)
    elif imscale == 'squareroot':
        brange = numpy.arange(zminfl**2,zmaxfl**2,(zmaxfl**2-zminfl**2)/1000)
    if imscale == 'linear':
        barimg = numpy.resize(brange,(1000,1))
    elif imscale == 'logarithmic':
        barimg = numpy.log10(numpy.resize(brange,(1000,1)))        
    elif imscale == 'squareroot':
        barimg = numpy.sqrt(numpy.resize(brange,(1000,1)))        
    try:
        nrm = len(str(int(numpy.nanmax(brange))))-1
    except:
        nrm = 0
    brange = brange / 10**nrm
    pylab.imshow(barimg,aspect='auto',interpolation='nearest',origin='lower',
                 vmin=numpy.nanmin(barimg),vmax=numpy.nanmax(barimg),
                 extent=(0.0,1.0,brange[0],brange[-1]),cmap=colmap)
    barwin.yaxis.tick_right()
    barwin.yaxis.set_label_position('right')
    barwin.yaxis.set_major_locator(MaxNLocator(7))
    pylab.gca().yaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False))
    pylab.gca().set_autoscale_on(False)
    pylab.setp(pylab.gca(),xticklabels=[],xticks=[])
    pylab.ylabel('Flux (10$^%d$ e$^-$ s$^{-1}$)' % nrm)
    setp(barwin.get_yticklabels(), 'rotation', 90)
    barwin.yaxis.set_major_formatter(ticker.FormatStrFormatter('%.1f'))

# plot residual color bar

#    barwin = pylab.axes([0.84,0.08,0.06,0.45])
#    Brange = numpy.arange(-zmaxre,zmaxre,(zmaxre+zmaxre)/1000)
#    try:
#        nrm = len(str(int(numpy.nanmax(brange))))-1
#    except:
#        nrm = 0
#    brange = brange / 10**nrm
#    barimg = numpy.resize(brange,(1000,1))
#    pylab.imshow(barimg,aspect='auto',interpolation='nearest',origin='lower',
#           vmin=brange[0],vmax=brange[-1],extent=(0.0,1.0,brange[0],brange[-1]),cmap=colmap)
#    barwin.yaxis.tick_right()
#    barwin.yaxis.set_label_position('right')
#    barwin.yaxis.set_major_formatter(ticker.FormatStrFormatter('%.1f'))
#    barwin.yaxis.set_major_locator(MaxNLocator(7))
#    pylab.gca().yaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False))
#    pylab.gca().set_autoscale_on(False)
#    pylab.setp(pylab.gca(),xticklabels=[],xticks=[])
#    pylab.ylabel('Residual (10$^%d$ e$^-$ s$^{-1}$)' % nrm)
#    setp(barwin.get_yticklabels(), 'rotation', 90)

# render plot

    if status == 0 and len(plotfile) > 0 and plotfile.lower() != 'none':
        pylab.savefig(plotfile)
    if status == 0 and plt:
        if cmdLine: 
            pylab.show(block=True)
        else: 
            pylab.ion()
            pylab.plot([])
            pylab.ioff()
	
# stop time

    kepmsg.clock('\nKEPPRF ended at',logfile,verbose)

    return
Esempio n. 2
0
def kepprf(infile,
           plotfile,
           rownum,
           columns,
           rows,
           fluxes,
           border,
           background,
           focus,
           prfdir,
           xtol,
           ftol,
           imscale,
           colmap,
           labcol,
           apercol,
           plt,
           verbose,
           logfile,
           status,
           cmdLine=False):

    # input arguments

    status = 0
    seterr(all="ignore")

    # log the call

    hashline = '----------------------------------------------------------------------------'
    kepmsg.log(logfile, hashline, verbose)
    call = 'KEPPRF -- '
    call += 'infile=' + infile + ' '
    call += 'plotfile=' + plotfile + ' '
    call += 'rownum=' + str(rownum) + ' '
    call += 'columns=' + columns + ' '
    call += 'rows=' + rows + ' '
    call += 'fluxes=' + fluxes + ' '
    call += 'border=' + str(border) + ' '
    bground = 'n'
    if (background): bground = 'y'
    call += 'background=' + bground + ' '
    focs = 'n'
    if (focus): focs = 'y'
    call += 'focus=' + focs + ' '
    call += 'prfdir=' + prfdir + ' '
    call += 'xtol=' + str(xtol) + ' '
    call += 'ftol=' + str(xtol) + ' '
    call += 'imscale=' + imscale + ' '
    call += 'colmap=' + colmap + ' '
    call += 'labcol=' + labcol + ' '
    call += 'apercol=' + apercol + ' '
    plotit = 'n'
    if (plt): plotit = 'y'
    call += 'plot=' + plotit + ' '
    chatter = 'n'
    if (verbose): chatter = 'y'
    call += 'verbose=' + chatter + ' '
    call += 'logfile=' + logfile
    kepmsg.log(logfile, call + '\n', verbose)

    # test log file

    logfile = kepmsg.test(logfile)

    # start time

    kepmsg.clock('KEPPRF started at', logfile, verbose)

    # reference color map

    if colmap == 'browse':
        status = cmap_plot(cmdLine)

# construct inital guess vector for fit

    if status == 0:
        guess = []
        try:
            f = fluxes.strip().split(',')
            x = columns.strip().split(',')
            y = rows.strip().split(',')
            for i in range(len(f)):
                f[i] = float(f[i])
        except:
            f = fluxes
            x = columns
            y = rows
        nsrc = len(f)
        for i in range(nsrc):
            try:
                guess.append(float(f[i]))
            except:
                message = 'ERROR -- KEPPRF: Fluxes must be floating point numbers'
                status = kepmsg.err(logfile, message, verbose)
        if status == 0:
            if len(x) != nsrc or len(y) != nsrc:
                message = 'ERROR -- KEPFIT:FITMULTIPRF: Guesses for rows, columns and '
                message += 'fluxes must have the same number of sources'
                status = kepmsg.err(logfile, message, verbose)
        if status == 0:
            for i in range(nsrc):
                try:
                    guess.append(float(x[i]))
                except:
                    message = 'ERROR -- KEPPRF: Columns must be floating point numbers'
                    status = kepmsg.err(logfile, message, verbose)
        if status == 0:
            for i in range(nsrc):
                try:
                    guess.append(float(y[i]))
                except:
                    message = 'ERROR -- KEPPRF: Rows must be floating point numbers'
                    status = kepmsg.err(logfile, message, verbose)
        if status == 0 and background:
            if border == 0:
                guess.append(0.0)
            else:
                for i in range((border + 1) * 2):
                    guess.append(0.0)
        if status == 0 and focus:
            guess.append(1.0)
            guess.append(1.0)
            guess.append(0.0)

# open TPF FITS file

    if status == 0:
        try:
            kepid, channel, skygroup, module, output, quarter, season, \
                ra, dec, column, row, kepmag, xdim, ydim, barytime, status = \
                kepio.readTPF(infile,'TIME',logfile,verbose)
        except:
            message = 'ERROR -- KEPPRF: is %s a Target Pixel File? ' % infile
            status = kepmsg.err(logfile, message, verbose)
    if status == 0:
        kepid, channel, skygroup, module, output, quarter, season, \
            ra, dec, column, row, kepmag, xdim, ydim, tcorr, status = \
            kepio.readTPF(infile,'TIMECORR',logfile,verbose)
    if status == 0:
        kepid, channel, skygroup, module, output, quarter, season, \
            ra, dec, column, row, kepmag, xdim, ydim, cadno, status = \
            kepio.readTPF(infile,'CADENCENO',logfile,verbose)
    if status == 0:
        kepid, channel, skygroup, module, output, quarter, season, \
            ra, dec, column, row, kepmag, xdim, ydim, fluxpixels, status = \
            kepio.readTPF(infile,'FLUX',logfile,verbose)
    if status == 0:
        kepid, channel, skygroup, module, output, quarter, season, \
            ra, dec, column, row, kepmag, xdim, ydim, errpixels, status = \
            kepio.readTPF(infile,'FLUX_ERR',logfile,verbose)
    if status == 0:
        kepid, channel, skygroup, module, output, quarter, season, \
            ra, dec, column, row, kepmag, xdim, ydim, qual, status = \
            kepio.readTPF(infile,'QUALITY',logfile,verbose)

# read mask defintion data from TPF file

    if status == 0:
        maskimg, pixcoord1, pixcoord2, status = kepio.readMaskDefinition(
            infile, logfile, verbose)
        npix = numpy.size(numpy.nonzero(maskimg)[0])

# print target data

    if status == 0 and verbose:
        print('')
        print('      KepID: %s' % kepid)
        print('        BJD: %.2f' % (barytime[rownum - 1] + 2454833.0))
        print(' RA (J2000): %s' % ra)
        print('Dec (J2000):  %s' % dec)
        print('     KepMag:  %s' % kepmag)
        print('   SkyGroup:   %2s' % skygroup)
        print('     Season:   %2s' % str(season))
        print('    Channel:   %2s' % channel)
        print('     Module:   %2s' % module)
        print('     Output:    %1s' % output)
        print('')

# is this a good row with finite timestamp and pixels?

    if status == 0:
        if not numpy.isfinite(barytime[rownum - 1]) or numpy.nansum(
                fluxpixels[rownum - 1, :]) == numpy.nan:
            message = 'ERROR -- KEPFIELD: Row ' + str(
                rownum) + ' is a bad quality timestamp'
            status = kepmsg.err(logfile, message, verbose)

# construct input pixel image

    if status == 0:
        flux = fluxpixels[rownum - 1, :]
        ferr = errpixels[rownum - 1, :]
        DATx = arange(column, column + xdim)
        DATy = arange(row, row + ydim)
#        if numpy.nanmin > 420000.0: flux -= 420000.0

# image scale and intensity limits of pixel data

    if status == 0:
        n = 0
        DATimg = empty((ydim, xdim))
        ERRimg = empty((ydim, xdim))
        for i in range(ydim):
            for j in range(xdim):
                DATimg[i, j] = flux[n]
                ERRimg[i, j] = ferr[n]
                n += 1

# determine suitable PRF calibration file

    if status == 0:
        if int(module) < 10:
            prefix = 'kplr0'
        else:
            prefix = 'kplr'
        prfglob = prfdir + '/' + prefix + str(module) + '.' + str(
            output) + '*' + '_prf.fits'
        try:
            prffile = glob.glob(prfglob)[0]
        except:
            message = 'ERROR -- KEPPRF: No PRF file found in ' + prfdir
            status = kepmsg.err(logfile, message, verbose)

# read PRF images

    if status == 0:
        prfn = [0, 0, 0, 0, 0]
        crpix1p = numpy.zeros((5), dtype='float32')
        crpix2p = numpy.zeros((5), dtype='float32')
        crval1p = numpy.zeros((5), dtype='float32')
        crval2p = numpy.zeros((5), dtype='float32')
        cdelt1p = numpy.zeros((5), dtype='float32')
        cdelt2p = numpy.zeros((5), dtype='float32')
        for i in range(5):
            prfn[i], crpix1p[i], crpix2p[i], crval1p[i], crval2p[i], cdelt1p[i], cdelt2p[i], status \
                = kepio.readPRFimage(prffile,i+1,logfile,verbose)
        prfn = array(prfn)
        PRFx = arange(0.5, shape(prfn[0])[1] + 0.5)
        PRFy = arange(0.5, shape(prfn[0])[0] + 0.5)
        PRFx = (PRFx - size(PRFx) / 2) * cdelt1p[0]
        PRFy = (PRFy - size(PRFy) / 2) * cdelt2p[0]

# interpolate the calibrated PRF shape to the target position

    if status == 0:
        prf = zeros(shape(prfn[0]), dtype='float32')
        prfWeight = zeros((5), dtype='float32')
        for i in range(5):
            prfWeight[i] = sqrt((column - crval1p[i])**2 +
                                (row - crval2p[i])**2)
            if prfWeight[i] == 0.0:
                prfWeight[i] = 1.0e-6
            prf = prf + prfn[i] / prfWeight[i]
        prf = prf / nansum(prf) / cdelt1p[0] / cdelt2p[0]

# interpolate the calibrated PRF shape to the target position

#    if status == 0:
#        prf = zeros(shape(prfn[0,:,:]),dtype='float32')
#        px = crval1p + len(PRFx) / 2 * cdelt1p[0]
#        py = crval2p + len(PRFy) / 2 * cdelt2p[0]
#        pp = [[px[0],py[0]],
#              [px[1],py[1]],
#              [px[2],py[2]],
#              [px[3],py[3]],
#              [px[4],py[4]]]
#        for index,value in ndenumerate(prf):
#            pz = prfn[:,index[0],index[1]]
#            prf[index] = griddata(pp, pz, ([column], [row]), method='linear')
#        print shape(prf)

# location of the data image centered on the PRF image (in PRF pixel units)

    if status == 0:
        prfDimY = int(ydim / cdelt1p[0])
        prfDimX = int(xdim / cdelt2p[0])
        PRFy0 = (shape(prf)[0] - prfDimY) / 2
        PRFx0 = (shape(prf)[1] - prfDimX) / 2

# interpolation function over the PRF

    if status == 0:
        splineInterpolation = scipy.interpolate.RectBivariateSpline(
            PRFx, PRFy, prf)

# construct mesh for background model

    if status == 0 and background:
        bx = numpy.arange(1., float(xdim + 1))
        by = numpy.arange(1., float(ydim + 1))
        xx, yy = numpy.meshgrid(numpy.linspace(bx.min(), bx.max(), xdim),
                                numpy.linspace(by.min(), by.max(), ydim))

# fit PRF model to pixel data

    if status == 0:
        start = time.time()
        if focus and background:
            args = (DATx, DATy, DATimg, ERRimg, nsrc, border, xx, yy,
                    splineInterpolation, float(x[0]), float(y[0]))
            ans = fmin_powell(kepfunc.PRFwithFocusAndBackground,
                              guess,
                              args=args,
                              xtol=xtol,
                              ftol=ftol,
                              disp=False)
        elif focus and not background:
            args = (DATx, DATy, DATimg, ERRimg, nsrc, splineInterpolation,
                    float(x[0]), float(y[0]))
            ans = fmin_powell(kepfunc.PRFwithFocus,
                              guess,
                              args=args,
                              xtol=xtol,
                              ftol=ftol,
                              disp=False)
        elif background and not focus:
            args = (DATx, DATy, DATimg, ERRimg, nsrc, border, xx, yy,
                    splineInterpolation, float(x[0]), float(y[0]))
            ans = fmin_powell(kepfunc.PRFwithBackground,
                              guess,
                              args=args,
                              xtol=xtol,
                              ftol=ftol,
                              disp=False)
        else:
            args = (DATx, DATy, DATimg, ERRimg, nsrc, splineInterpolation,
                    float(x[0]), float(y[0]))
            ans = fmin_powell(kepfunc.PRF,
                              guess,
                              args=args,
                              xtol=xtol,
                              ftol=ftol,
                              disp=False)
        print('Convergence time = %.2fs\n' % (time.time() - start))

# pad the PRF data if the PRF array is smaller than the data array

    if status == 0:
        flux = []
        OBJx = []
        OBJy = []
        PRFmod = numpy.zeros((prfDimY, prfDimX))
        if PRFy0 < 0 or PRFx0 < 0.0:
            PRFmod = numpy.zeros((prfDimY, prfDimX))
            superPRF = zeros((prfDimY + 1, prfDimX + 1))
            superPRF[abs(PRFy0):abs(PRFy0) + shape(prf)[0],
                     abs(PRFx0):abs(PRFx0) + shape(prf)[1]] = prf
            prf = superPRF * 1.0
            PRFy0 = 0
            PRFx0 = 0

# rotate the PRF model around its center

        if focus:
            angle = ans[-1]
            prf = rotate(prf, -angle, reshape=False, mode='nearest')

# iterate through the sources in the best fit PSF model

        for i in range(nsrc):
            flux.append(ans[i])
            OBJx.append(ans[nsrc + i])
            OBJy.append(ans[nsrc * 2 + i])

            # calculate best-fit model

            y = (OBJy[i] - mean(DATy)) / cdelt1p[0]
            x = (OBJx[i] - mean(DATx)) / cdelt2p[0]
            prfTmp = shift(prf, [y, x], order=3, mode='constant')
            prfTmp = prfTmp[PRFy0:PRFy0 + prfDimY, PRFx0:PRFx0 + prfDimX]
            PRFmod = PRFmod + prfTmp * flux[i]
            wx = 1.0
            wy = 1.0
            angle = 0
            b = 0.0

            # write out best fit parameters

            if verbose:
                txt = 'Flux = %10.2f e-/s ' % flux[i]
                txt += 'X = %9.4f pix ' % OBJx[i]
                txt += 'Y = %9.4f pix ' % OBJy[i]
                kepmsg.log(logfile, txt, True)
#
#        params = {'backend': 'png',
#                  'axes.linewidth': 2.5,
#                  'axes.labelsize': 24,
#                  'axes.font': 'sans-serif',
#                  'axes.fontweight' : 'bold',
#                  'text.fontsize': 12,
#                  'legend.fontsize': 12,
#                  'xtick.labelsize': 24,
#                  'ytick.labelsize': 24}
#        pylab.rcParams.update(params)
#
#        pylab.figure(figsize=[20,10])
#        ax = pylab.axes([0.05,0.08,0.46,0.9])
#        xxx = numpy.arange(397.5,402.5,0.02)
#        yyy = numpy.sum(PRFmod,axis=0) / numpy.max(numpy.sum(PRFmod,axis=0))
#        pylab.plot(xxx,yyy,color='b',linewidth=3.0)
#        xxx = numpy.append(numpy.insert(xxx,[0],[xxx[0]]),xxx[-1])
#        yyy = numpy.append(numpy.insert(yyy,[0],[0.0]),yyy[-1])
#        pylab.fill(xxx,yyy,fc='y',linewidth=0.0,alpha=0.3)
#        pylab.xlabel('Pixel Column Number')
#        pylab.xlim(397.5,402.5)
#        pylab.ylim(1.0e-30,1.02)
#        for xmaj in numpy.arange(397.5,402.5,1.0):
#            pylab.plot([xmaj,xmaj],[0.0,1.1],color='k',linewidth=0.5,linestyle=':')
#        for xmaj in numpy.arange(0.2,1.2,0.2):
#            pylab.plot([0.0,2000.0],[xmaj,xmaj],color='k',linewidth=0.5,linestyle=':')
#
#
#        ax = pylab.axes([0.51,0.08,0.46,0.9])
#        xxx = numpy.arange(32.5,37.5,0.02)
#        yyy = numpy.sum(PRFmod,axis=1) / numpy.max(numpy.sum(PRFmod,axis=1))
#        pylab.plot(xxx,yyy,color='b',linewidth=3.0)
#        xxx = numpy.append(numpy.insert(xxx,[0],[xxx[0]]),xxx[-1])
#        yyy = numpy.append(numpy.insert(yyy,[0],[0.0]),yyy[-1])
#        pylab.fill(xxx,yyy,fc='y',linewidth=0.0,alpha=0.3)
#        pylab.setp(pylab.gca(),yticklabels=[])
#        pylab.xlabel('Pixel Row Number')
#        pylab.xlim(32.5,37.5)
#        pylab.ylim(1.0e-30,1.02)
#        for xmaj in numpy.arange(32.5,37.5,1.0):
#            pylab.plot([xmaj,xmaj],[0.0,1.1],color='k',linewidth=0.5,linestyle=':')
#        for xmaj in numpy.arange(0.2,1.2,0.2):
#            pylab.plot([0.0,2000.0],[xmaj,xmaj],color='k',linewidth=0.5,linestyle=':')
#        pylab.ion()
#        pylab.plot([])
#        pylab.ioff()

        if verbose and background:
            bterms = border + 1
            if bterms == 1:
                b = ans[nsrc * 3]
            else:
                bcoeff = array([
                    ans[nsrc * 3:nsrc * 3 + bterms],
                    ans[nsrc * 3 + bterms:nsrc * 3 + bterms * 2]
                ])
                bkg = kepfunc.polyval2d(xx, yy, bcoeff)
                b = nanmean(bkg.reshape(bkg.size))
            txt = '\n   Mean background = %.2f e-/s' % b
            kepmsg.log(logfile, txt, True)
        if focus:
            wx = ans[-3]
            wy = ans[-2]
            angle = ans[-1]
        if verbose and focus:
            if not background: kepmsg.log(logfile, '', True)
            kepmsg.log(logfile, ' X/Y focus factors = %.3f/%.3f' % (wx, wy),
                       True)
            kepmsg.log(logfile, 'PRF rotation angle = %.2f deg' % angle, True)

# measure flux fraction and contamination

# LUGER: This looks horribly bugged. ``PRFall`` is certainly NOT the sum of the all the sources.

    if status == 0:
        PRFall = kepfunc.PRF2DET(flux, OBJx, OBJy, DATx, DATy, wx, wy, angle,
                                 splineInterpolation)
        PRFone = kepfunc.PRF2DET([flux[0]], [OBJx[0]], [OBJy[0]], DATx, DATy,
                                 wx, wy, angle, splineInterpolation)

        # LUGER: Add up contaminant fluxes
        PRFcont = np.zeros_like(PRFone)
        for ncont in range(1, len(flux)):
            PRFcont += kepfunc.PRF2DET([flux[ncont]], [OBJx[ncont]],
                                       [OBJy[ncont]], DATx, DATy, wx, wy,
                                       angle, splineInterpolation)
        PRFcont[np.where(PRFcont < 0)] = 0

        FluxInMaskAll = numpy.nansum(PRFall)
        FluxInMaskOne = numpy.nansum(PRFone)
        FluxInAperAll = 0.0
        FluxInAperOne = 0.0
        FluxInAperAllTrue = 0.0

        for i in range(1, ydim):
            for j in range(1, xdim):
                if kepstat.bitInBitmap(maskimg[i, j], 2):
                    FluxInAperAll += PRFall[i, j]
                    FluxInAperOne += PRFone[i, j]
                    FluxInAperAllTrue += PRFone[i, j] + PRFcont[i, j]
        FluxFraction = FluxInAperOne / flux[0]
        try:
            Contamination = (FluxInAperAll - FluxInAperOne) / FluxInAperAll
        except:
            Contamination = 0.0

        # LUGER: Pixel crowding metrics
        Crowding = PRFone / (PRFone + PRFcont)

        # LUGER: Optimal aperture crowding metric
        CrowdAper = FluxInAperOne / FluxInAperAllTrue

        kepmsg.log(
            logfile,
            '\n                Total flux in mask = %.2f e-/s' % FluxInMaskAll,
            True)
        kepmsg.log(
            logfile,
            '               Target flux in mask = %.2f e-/s' % FluxInMaskOne,
            True)
        kepmsg.log(
            logfile,
            '            Total flux in aperture = %.2f e-/s' % FluxInAperAll,
            True)
        kepmsg.log(
            logfile,
            '           Target flux in aperture = %.2f e-/s' % FluxInAperOne,
            True)
        kepmsg.log(
            logfile, '  Target flux fraction in aperture = %.2f%%' %
            (FluxFraction * 100.0), True)
        kepmsg.log(
            logfile, 'Contamination fraction in aperture = %.2f%%' %
            (Contamination * 100.0), True)
        kepmsg.log(logfile,
                   '       Crowding metric in aperture = %.4f' % (CrowdAper),
                   True)

# constuct model PRF in detector coordinates

    if status == 0:
        PRFfit = PRFall + 0.0
        if background and bterms == 1:
            PRFfit = PRFall + b
        if background and bterms > 1:
            PRFfit = PRFall + bkg

# calculate residual of DATA - FIT

    if status == 0:
        PRFres = DATimg - PRFfit
        FLUXres = numpy.nansum(PRFres) / npix

# calculate the sum squared difference between data and model

    if status == 0:
        Pearson = abs(numpy.nansum(numpy.square(DATimg - PRFfit) / PRFfit))
        Chi2 = numpy.nansum(
            numpy.square(DATimg - PRFfit) / numpy.square(ERRimg))
        DegOfFreedom = npix - len(guess) - 1
        try:
            kepmsg.log(logfile, '\n       Residual flux = %.2f e-/s' % FLUXres,
                       True)
            kepmsg.log(
                logfile, 'Pearson\'s chi^2 test = %d for %d dof' %
                (Pearson, DegOfFreedom), True)
        except:
            pass
        kepmsg.log(
            logfile,
            '          Chi^2 test = %d for %d dof' % (Chi2, DegOfFreedom),
            True)

# image scale and intensity limits for plotting images

    if status == 0:
        imgdat_pl, zminfl, zmaxfl = kepplot.intScale2D(DATimg, imscale)
        imgprf_pl, zminpr, zmaxpr = kepplot.intScale2D(PRFmod, imscale)
        imgfit_pl, zminfi, zmaxfi = kepplot.intScale2D(PRFfit, imscale)
        imgres_pl, zminre, zmaxre = kepplot.intScale2D(PRFres, 'linear')
        if imscale == 'linear':
            zmaxpr *= 0.9
        elif imscale == 'logarithmic':
            zmaxpr = numpy.max(zmaxpr)
            zminpr = zmaxpr / 2

# plot style

    if status == 0:
        pylab.figure(figsize=[12, 10])
        pylab.clf()
        plotimage(imgdat_pl, zminfl, zmaxfl, 1, row, column, xdim, ydim, 0.07,
                  0.53, 'observation', colmap, labcol)
        #        pylab.text(830.0,242.1,'A',horizontalalignment='center',verticalalignment='center',
        #                   fontsize=28,fontweight=500,color='white')
        #        pylab.text(831.1,240.62,'B',horizontalalignment='center',verticalalignment='center',
        #                   fontsize=28,fontweight=500,color='white')
        #        plotimage(imgprf_pl,0.0,zmaxpr/0.5,2,row,column,xdim,ydim,0.52,0.52,'model',colmap)
        plotimage(imgprf_pl, zminpr, zmaxpr, 2, row, column, xdim, ydim, 0.44,
                  0.53, 'model', colmap, labcol)
        kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 1, apercol,
                        '--', 0.5)
        kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 2, apercol,
                        '-', 3.0)
        plotimage(imgfit_pl,
                  zminfl,
                  zmaxfl,
                  3,
                  row,
                  column,
                  xdim,
                  ydim,
                  0.07,
                  0.08,
                  'fit',
                  colmap,
                  labcol,
                  crowd=Crowding)
        #        plotimage(imgres_pl,-zmaxre,zmaxre,4,row,column,xdim,ydim,0.44,0.08,'residual',colmap,'k')
        plotimage(imgres_pl, zminfl, zmaxfl, 4, row, column, xdim, ydim, 0.44,
                  0.08, 'residual', colmap, labcol)

# plot data color bar

#    barwin = pylab.axes([0.84,0.53,0.06,0.45])
    barwin = pylab.axes([0.84, 0.08, 0.06, 0.9])
    if imscale == 'linear':
        brange = numpy.arange(zminfl, zmaxfl, (zmaxfl - zminfl) / 1000)
    elif imscale == 'logarithmic':
        brange = numpy.arange(10.0**zminfl, 10.0**zmaxfl,
                              (10.0**zmaxfl - 10.0**zminfl) / 1000)
    elif imscale == 'squareroot':
        brange = numpy.arange(zminfl**2, zmaxfl**2,
                              (zmaxfl**2 - zminfl**2) / 1000)
    if imscale == 'linear':
        barimg = numpy.resize(brange, (1000, 1))
    elif imscale == 'logarithmic':
        barimg = numpy.log10(numpy.resize(brange, (1000, 1)))
    elif imscale == 'squareroot':
        barimg = numpy.sqrt(numpy.resize(brange, (1000, 1)))
    try:
        nrm = len(str(int(numpy.nanmax(brange)))) - 1
    except:
        nrm = 0
    brange = brange / 10**nrm
    pylab.imshow(barimg,
                 aspect='auto',
                 interpolation='nearest',
                 origin='lower',
                 vmin=numpy.nanmin(barimg),
                 vmax=numpy.nanmax(barimg),
                 extent=(0.0, 1.0, brange[0], brange[-1]),
                 cmap=colmap)
    barwin.yaxis.tick_right()
    barwin.yaxis.set_label_position('right')
    barwin.yaxis.set_major_locator(MaxNLocator(7))
    pylab.gca().yaxis.set_major_formatter(
        pylab.ScalarFormatter(useOffset=False))
    pylab.gca().set_autoscale_on(False)
    pylab.setp(pylab.gca(), xticklabels=[], xticks=[])
    pylab.ylabel('Flux (10$^%d$ e$^-$ s$^{-1}$)' % nrm)
    setp(barwin.get_yticklabels(), 'rotation', 90)
    barwin.yaxis.set_major_formatter(ticker.FormatStrFormatter('%.1f'))

    # plot residual color bar

    #    barwin = pylab.axes([0.84,0.08,0.06,0.45])
    #    Brange = numpy.arange(-zmaxre,zmaxre,(zmaxre+zmaxre)/1000)
    #    try:
    #        nrm = len(str(int(numpy.nanmax(brange))))-1
    #    except:
    #        nrm = 0
    #    brange = brange / 10**nrm
    #    barimg = numpy.resize(brange,(1000,1))
    #    pylab.imshow(barimg,aspect='auto',interpolation='nearest',origin='lower',
    #           vmin=brange[0],vmax=brange[-1],extent=(0.0,1.0,brange[0],brange[-1]),cmap=colmap)
    #    barwin.yaxis.tick_right()
    #    barwin.yaxis.set_label_position('right')
    #    barwin.yaxis.set_major_formatter(ticker.FormatStrFormatter('%.1f'))
    #    barwin.yaxis.set_major_locator(MaxNLocator(7))
    #    pylab.gca().yaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False))
    #    pylab.gca().set_autoscale_on(False)
    #    pylab.setp(pylab.gca(),xticklabels=[],xticks=[])
    #    pylab.ylabel('Residual (10$^%d$ e$^-$ s$^{-1}$)' % nrm)
    #    setp(barwin.get_yticklabels(), 'rotation', 90)

    # render plot

    if status == 0 and len(plotfile) > 0 and plotfile.lower() != 'none':
        pylab.savefig(plotfile)
    if status == 0 and plt:
        if cmdLine:
            pylab.show(block=True)
        else:
            pylab.ion()
            pylab.plot([])
            pylab.ioff()

# stop time

    kepmsg.clock('\nKEPPRF ended at', logfile, verbose)

    return
Esempio n. 3
0
def PrfBorders(maskimg,xdim,ydim,pixcoord1,pixcoord2,bit,lcolor,lstyle,lwidth):

    for i in range(1,ydim):
        for j in range(1,xdim):
            if kepstat.bitInBitmap(maskimg[i,j],bit) and not kepstat.bitInBitmap(maskimg[i-1,j],bit):
                x = array([pixcoord1[j-1,i],pixcoord1[j,i]]) + 0.5
                y = array([pixcoord2[j,i],pixcoord2[j,i]]) - 0.5
                pylab.plot(x*50,y*50,color=lcolor,linestyle=lstyle,linewidth=lwidth)
            if not kepstat.bitInBitmap(maskimg[i,j],bit) and kepstat.bitInBitmap(maskimg[i-1,j],bit):
                x = array([pixcoord1[j-1,i],pixcoord1[j,i]]) + 0.5
                y = array([pixcoord2[j,i],pixcoord2[j,i]]) - 0.5
                pylab.plot(x*50,y*50,color=lcolor,linestyle=lstyle,linewidth=lwidth)
            if kepstat.bitInBitmap(maskimg[i,j],bit) and not kepstat.bitInBitmap(maskimg[i,j-1],bit):
                x = array([pixcoord1[j,i],pixcoord1[j,i]]) - 0.5
                y = array([pixcoord2[j,i-1],pixcoord2[j,i]]) + 0.5
                pylab.plot(x*50,y*50,color=lcolor,linestyle=lstyle,linewidth=lwidth)
            if not kepstat.bitInBitmap(maskimg[i,j],bit) and kepstat.bitInBitmap(maskimg[i,j-1],bit):
                x = array([pixcoord1[j,i],pixcoord1[j,i]]) - 0.5
                y = array([pixcoord2[j,i-1],pixcoord2[j,i]]) + 0.5
                pylab.plot(x*50,y*50,color=lcolor,linestyle=lstyle,linewidth=lwidth)

# corner cases 

    for j in range(ydim):
        try:
            if kepstat.bitInBitmap(maskimg[j,0],bit) and not kepstat.bitInBitmap(maskimg[j-1,0],bit):
                x = array([pixcoord1[0,j],pixcoord1[1,j]]) - 0.5
                y = array([pixcoord2[0,j],pixcoord2[0,j]]) - 0.5
                pylab.plot(x,y,color=lcolor,linestyle=lstyle,linewidth=lwidth) 
        except:
            pass
        try:
            if not kepstat.bitInBitmap(maskimg[j+1,0],bit) and kepstat.bitInBitmap(maskimg[j,0],bit):
                x = array([pixcoord1[0,j],pixcoord1[1,j]]) - 0.5
                y = array([pixcoord2[0,j],pixcoord2[0,j]]) + 0.5
                pylab.plot(x,y,color=lcolor,linestyle=lstyle,linewidth=lwidth) 
        except:
            pass
        if kepstat.bitInBitmap(maskimg[j,0],bit):
            x = array([pixcoord1[0,j],pixcoord1[0,j]]) - 0.5
            try:
                y = array([pixcoord2[0,j],pixcoord2[0,j+1]]) - 0.5
            except:
                y = array([pixcoord2[0,j-1],pixcoord2[0,j]]) + 0.5
            pylab.plot(x,y,color=lcolor,linestyle=lstyle,linewidth=lwidth)
        if kepstat.bitInBitmap(maskimg[j,xdim-1],bit):
            x = array([pixcoord1[xdim-1,j],pixcoord1[xdim-1,j]]) + 0.5
            try:
                y = array([pixcoord2[xdim-1,j],pixcoord2[xdim-1,j+1]]) - 0.5
            except:
                y = array([pixcoord2[xdim-1,j-1],pixcoord2[xdim-1,j]]) + 0.5
            pylab.plot(x,y,color=lcolor,linestyle=lstyle,linewidth=lwidth)
    for i in range(xdim):
        try:
            if kepstat.bitInBitmap(maskimg[0,i],bit) and not kepstat.bitInBitmap(maskimg[0,i-1],bit):
                x = array([pixcoord1[i,0],pixcoord1[i,0]]) - 0.5
                y = array([pixcoord2[i,0],pixcoord2[i,1]]) - 0.5
                pylab.plot(x,y,color=lcolor,linestyle=lstyle,linewidth=lwidth) 
        except:
            pass
        try:
            if not kepstat.bitInBitmap(maskimg[0,i+1],bit) and kepstat.bitInBitmap(maskimg[0,i],bit):
                x = array([pixcoord1[i,0],pixcoord1[i,0]]) + 0.5
                y = array([pixcoord2[i,0],pixcoord2[i,1]]) - 0.5
                pylab.plot(x,y,color=lcolor,linestyle=lstyle,linewidth=lwidth) 
        except:
            pass
        if kepstat.bitInBitmap(maskimg[0,i],bit):
            try:
                x = array([pixcoord1[i,0],pixcoord1[i+1,0]]) - 0.5
            except:
                x = array([pixcoord1[i-1,0],pixcoord1[i,0]]) + 0.5
            y = array([pixcoord2[i,0],pixcoord2[i,0]]) - 0.5
            pylab.plot(x,y,color=lcolor,linestyle=lstyle,linewidth=lwidth)
        if kepstat.bitInBitmap(maskimg[ydim-1,i],bit):
            try:
                x = array([pixcoord1[i,ydim-1],pixcoord1[i+1,ydim-1]]) - 0.5
            except:
                x = array([pixcoord1[i-1,ydim-1],pixcoord1[i,ydim-1]]) - 0.5
            y = array([pixcoord2[i,ydim-1],pixcoord2[i,ydim-1]]) + 0.5
            pylab.plot(x,y,color=lcolor,linestyle=lstyle,linewidth=lwidth)
            
    if kepstat.bitInBitmap(maskimg[ydim-1,xdim-1],bit):
        x = array([pixcoord1[xdim-2,ydim-1],pixcoord1[xdim-1,ydim-1]]) + 0.5
        y = array([pixcoord2[xdim-1,ydim-1],pixcoord2[xdim-1,ydim-1]]) + 0.5
        pylab.plot(x,y,color=lcolor,linestyle=lstyle,linewidth=lwidth)

    if kepstat.bitInBitmap(maskimg[0,xdim-1],bit):
        x = array([pixcoord1[xdim-1,0],pixcoord1[xdim-1,0]]) + 0.5
        y = array([pixcoord2[xdim-1,0],pixcoord2[xdim-1,1]]) - 0.5
        pylab.plot(x,y,color=lcolor,linestyle=lstyle,linewidth=lwidth)

    return
Esempio n. 4
0
def keppixseries(infile,outfile,plotfile,plottype,filter,function,cutoff,clobber,verbose,logfile,status, cmdLine=False): 

# input arguments

    status = 0
    seterr(all="ignore") 

# log the call 

    hashline = '----------------------------------------------------------------------------'
    kepmsg.log(logfile,hashline,verbose)
    call = 'KEPPIXSERIES -- '
    call += 'infile='+infile+' '
    call += 'outfile='+outfile+' '
    call += 'plotfile='+plotfile+' '
    call += 'plottype='+plottype+' '
    filt = 'n'
    if (filter): filt = 'y'
    call += 'filter='+filt+ ' '
    call += 'function='+function+' '
    call += 'cutoff='+str(cutoff)+' '
    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('KEPPIXSERIES 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 -- KEPPIXSERIES: ' + outfile + ' exists. Use --clobber'
        status = kepmsg.err(logfile,message,verbose)

# 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, qual, status = \
            kepio.readTPF(infile,'QUALITY',logfile,verbose)

# read mask defintion data from TPF file

    if status == 0:
        maskimg, pixcoord1, pixcoord2, status = kepio.readMaskDefinition(infile,logfile,verbose)

# print target data

    if status == 0:
        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 ''

# how many quality = 0 rows?

    if status == 0:
        npts = 0
        nrows = len(fluxpixels)
        for i in range(nrows):
            if qual[i] == 0 and \
                    numpy.isfinite(barytime[i]) and \
                    numpy.isfinite(fluxpixels[i,ydim*xdim/2]):
                npts += 1
        time = empty((npts))
        timecorr = empty((npts))
        cadenceno = empty((npts))
        quality = empty((npts))
        pixseries = empty((ydim,xdim,npts))
        errseries = empty((ydim,xdim,npts))

# construct output light curves

    if status == 0:
        np = 0
        for i in range(ydim):
            for j in range(xdim):
                npts = 0
                for k in range(nrows):
                    if qual[k] == 0 and \
                    numpy.isfinite(barytime[k]) and \
                    numpy.isfinite(fluxpixels[k,ydim*xdim/2]):
                        time[npts] = barytime[k]
                        timecorr[npts] = tcorr[k]
                        cadenceno[npts] = cadno[k]
                        quality[npts] = qual[k]
                        pixseries[i,j,npts] = fluxpixels[k,np]
                        errseries[i,j,npts] = errpixels[k,np]
                        npts += 1
                np += 1

# define data sampling

    if status == 0 and filter:
        tpf, status = kepio.openfits(infile,'readonly',logfile,verbose)
    if status == 0 and filter:
        cadence, status = kepkey.cadence(tpf[1],infile,logfile,verbose)     
        tr = 1.0 / (cadence / 86400)
        timescale = 1.0 / (cutoff / tr)

# define convolution function

    if status == 0 and filter:
        if function == 'boxcar':
            filtfunc = numpy.ones(numpy.ceil(timescale))
        elif function == 'gauss':
            timescale /= 2
            dx = numpy.ceil(timescale * 10 + 1)
            filtfunc = kepfunc.gauss()
            filtfunc = filtfunc([1.0,dx/2-1.0,timescale],linspace(0,dx-1,dx))
        elif function == 'sinc':
            dx = numpy.ceil(timescale * 12 + 1)
            fx = linspace(0,dx-1,dx)
            fx = fx - dx / 2 + 0.5
            fx /= timescale
            filtfunc = numpy.sinc(fx)
        filtfunc /= numpy.sum(filtfunc)

# pad time series at both ends with noise model

    if status == 0 and filter:
        for i in range(ydim):
            for j in range(xdim):
                ave, sigma  = kepstat.stdev(pixseries[i,j,:len(filtfunc)])
                padded = numpy.append(kepstat.randarray(numpy.ones(len(filtfunc)) * ave, \
                                                            numpy.ones(len(filtfunc)) * sigma), pixseries[i,j,:])
                ave, sigma  = kepstat.stdev(pixseries[i,j,-len(filtfunc):])
                padded = numpy.append(padded, kepstat.randarray(numpy.ones(len(filtfunc)) * ave, \
                                                                    numpy.ones(len(filtfunc)) * sigma))

# convolve data

                if status == 0:
                    convolved = convolve(padded,filtfunc,'same')

# remove padding from the output array

                if status == 0:
                    outdata = convolved[len(filtfunc):-len(filtfunc)]
            
# subtract low frequencies

                if status == 0:
                    outmedian = median(outdata)
                    pixseries[i,j,:] = pixseries[i,j,:] - outdata + outmedian

# construct output file

    if status == 0 and ydim*xdim < 1000:
        instruct, status = kepio.openfits(infile,'readonly',logfile,verbose)
        status = kepkey.history(call,instruct[0],outfile,logfile,verbose)
        hdulist = HDUList(instruct[0])
        cols = []
        cols.append(Column(name='TIME',format='D',unit='BJD - 2454833',disp='D12.7',array=time))
        cols.append(Column(name='TIMECORR',format='E',unit='d',disp='E13.6',array=timecorr))
        cols.append(Column(name='CADENCENO',format='J',disp='I10',array=cadenceno))
        cols.append(Column(name='QUALITY',format='J',array=quality))
        for i in range(ydim):
            for j in range(xdim):
                colname = 'COL%d_ROW%d' % (i+column,j+row)
                cols.append(Column(name=colname,format='E',disp='E13.6',array=pixseries[i,j,:]))
        hdu1 = new_table(ColDefs(cols))
        try:
            hdu1.header.update('INHERIT',True,'inherit the primary header')
        except:
            status = 0
        try:
            hdu1.header.update('EXTNAME','PIXELSERIES','name of extension')
        except:
            status = 0
        try:
            hdu1.header.update('EXTVER',instruct[1].header['EXTVER'],'extension version number (not format version)')
        except:
            status = 0
        try:
            hdu1.header.update('TELESCOP',instruct[1].header['TELESCOP'],'telescope')
        except:
            status = 0
        try:
            hdu1.header.update('INSTRUME',instruct[1].header['INSTRUME'],'detector type')
        except:
            status = 0
        try:
            hdu1.header.update('OBJECT',instruct[1].header['OBJECT'],'string version of KEPLERID')
        except:
            status = 0
        try:
            hdu1.header.update('KEPLERID',instruct[1].header['KEPLERID'],'unique Kepler target identifier')
        except:
            status = 0
        try:
            hdu1.header.update('RADESYS',instruct[1].header['RADESYS'],'reference frame of celestial coordinates')
        except:
            status = 0
        try:
            hdu1.header.update('RA_OBJ',instruct[1].header['RA_OBJ'],'[deg] right ascension from KIC')
        except:
            status = 0
        try:
            hdu1.header.update('DEC_OBJ',instruct[1].header['DEC_OBJ'],'[deg] declination from KIC')
        except:
            status = 0
        try:
            hdu1.header.update('EQUINOX',instruct[1].header['EQUINOX'],'equinox of celestial coordinate system')
        except:
            status = 0
        try:
            hdu1.header.update('TIMEREF',instruct[1].header['TIMEREF'],'barycentric correction applied to times')
        except:
            status = 0
        try:
            hdu1.header.update('TASSIGN',instruct[1].header['TASSIGN'],'where time is assigned')
        except:
            status = 0
        try:
            hdu1.header.update('TIMESYS',instruct[1].header['TIMESYS'],'time system is barycentric JD')
        except:
            status = 0
        try:
            hdu1.header.update('BJDREFI',instruct[1].header['BJDREFI'],'integer part of BJD reference date')
        except:
            status = 0
        try:
            hdu1.header.update('BJDREFF',instruct[1].header['BJDREFF'],'fraction of the day in BJD reference date')
        except:
            status = 0
        try:
            hdu1.header.update('TIMEUNIT',instruct[1].header['TIMEUNIT'],'time unit for TIME, TSTART and TSTOP')
        except:
            status = 0
        try:
            hdu1.header.update('TSTART',instruct[1].header['TSTART'],'observation start time in BJD-BJDREF')
        except:
            status = 0
        try:
            hdu1.header.update('TSTOP',instruct[1].header['TSTOP'],'observation stop time in BJD-BJDREF')
        except:
            status = 0
        try:
            hdu1.header.update('LC_START',instruct[1].header['LC_START'],'mid point of first cadence in MJD')
        except:
            status = 0
        try:
            hdu1.header.update('LC_END',instruct[1].header['LC_END'],'mid point of last cadence in MJD')
        except:
            status = 0
        try:
            hdu1.header.update('TELAPSE',instruct[1].header['TELAPSE'],'[d] TSTOP - TSTART')
        except:
            status = 0
        try:
            hdu1.header.update('LIVETIME',instruct[1].header['LIVETIME'],'[d] TELAPSE multiplied by DEADC')
        except:
            status = 0
        try:
            hdu1.header.update('EXPOSURE',instruct[1].header['EXPOSURE'],'[d] time on source')
        except:
            status = 0
        try:
            hdu1.header.update('DEADC',instruct[1].header['DEADC'],'deadtime correction')
        except:
            status = 0
        try:
            hdu1.header.update('TIMEPIXR',instruct[1].header['TIMEPIXR'],'bin time beginning=0 middle=0.5 end=1')
        except:
            status = 0
        try:
            hdu1.header.update('TIERRELA',instruct[1].header['TIERRELA'],'[d] relative time error')
        except:
            status = 0
        try:
            hdu1.header.update('TIERABSO',instruct[1].header['TIERABSO'],'[d] absolute time error')
        except:
            status = 0
        try:
            hdu1.header.update('INT_TIME',instruct[1].header['INT_TIME'],'[s] photon accumulation time per frame')
        except:
            status = 0
        try:
            hdu1.header.update('READTIME',instruct[1].header['READTIME'],'[s] readout time per frame')
        except:
            status = 0
        try:
            hdu1.header.update('FRAMETIM',instruct[1].header['FRAMETIM'],'[s] frame time (INT_TIME + READTIME)')
        except:
            status = 0
        try:
            hdu1.header.update('NUM_FRM',instruct[1].header['NUM_FRM'],'number of frames per time stamp')
        except:
            status = 0
        try:
            hdu1.header.update('TIMEDEL',instruct[1].header['TIMEDEL'],'[d] time resolution of data')
        except:
            status = 0
        try:
            hdu1.header.update('DATE-OBS',instruct[1].header['DATE-OBS'],'TSTART as UTC calendar date')
        except:
            status = 0
        try:
            hdu1.header.update('DATE-END',instruct[1].header['DATE-END'],'TSTOP as UTC calendar date')
        except:
            status = 0
        try:
            hdu1.header.update('BACKAPP',instruct[1].header['BACKAPP'],'background is subtracted')
        except:
            status = 0
        try:
            hdu1.header.update('DEADAPP',instruct[1].header['DEADAPP'],'deadtime applied')
        except:
            status = 0
        try:
            hdu1.header.update('VIGNAPP',instruct[1].header['VIGNAPP'],'vignetting or collimator correction applied')
        except:
            status = 0
        try:
            hdu1.header.update('GAIN',instruct[1].header['GAIN'],'[electrons/count] channel gain')
        except:
            status = 0
        try:
            hdu1.header.update('READNOIS',instruct[1].header['READNOIS'],'[electrons] read noise')
        except:
            status = 0
        try:
            hdu1.header.update('NREADOUT',instruct[1].header['NREADOUT'],'number of read per cadence')
        except:
            status = 0
        try:
            hdu1.header.update('TIMSLICE',instruct[1].header['TIMSLICE'],'time-slice readout sequence section')
        except:
            status = 0
        try:
            hdu1.header.update('MEANBLCK',instruct[1].header['MEANBLCK'],'[count] FSW mean black level')
        except:
            status = 0
        hdulist.append(hdu1)
        hdulist.writeto(outfile)
        status = kepkey.new('EXTNAME','APERTURE','name of extension',instruct[2],outfile,logfile,verbose)
        pyfits.append(outfile,instruct[2].data,instruct[2].header)
        status = kepio.closefits(instruct,logfile,verbose)
    else:
        message = 'WARNING -- KEPPIXSERIES: output FITS file requires > 999 columns. Non-compliant with FITS convention.'

        kepmsg.warn(logfile,message)

# plot style

    if status == 0:
        try:
            params = {'backend': 'png',
                      'axes.linewidth': 2.0,
                      'axes.labelsize': 32,
                      'axes.font': 'sans-serif',
                      'axes.fontweight' : 'bold',
                      'text.fontsize': 8,
                      'legend.fontsize': 8,
                      'xtick.labelsize': 12,
                      'ytick.labelsize': 12}
            pylab.rcParams.update(params)
        except:
            pass

# plot pixel array

    fmin = 1.0e33
    fmax = -1.033
    if status == 0:
	pylab.figure(num=None,figsize=[12,12])
        pylab.clf()
        dx = 0.93 / xdim
        dy = 0.94 / ydim
        ax = pylab.axes([0.06,0.05,0.93,0.94])
        pylab.gca().xaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False))
        pylab.gca().yaxis.set_major_formatter(pylab.ScalarFormatter(useOffset=False))
        pylab.gca().xaxis.set_major_locator(matplotlib.ticker.MaxNLocator(integer=True))
        pylab.gca().yaxis.set_major_locator(matplotlib.ticker.MaxNLocator(integer=True))
        labels = ax.get_yticklabels()
        setp(labels, 'rotation', 90, fontsize=12)
        pylab.xlim(numpy.min(pixcoord1) - 0.5,numpy.max(pixcoord1) + 0.5)
        pylab.ylim(numpy.min(pixcoord2) - 0.5,numpy.max(pixcoord2) + 0.5)
        pylab.xlabel('time', {'color' : 'k'})
        pylab.ylabel('arbitrary flux', {'color' : 'k'})
        for i in range(ydim):
            for j in range(xdim):
                tmin = amin(time)
                tmax = amax(time)
                try:
                    numpy.isfinite(amin(pixseries[i,j,:]))
                    numpy.isfinite(amin(pixseries[i,j,:]))
                    fmin = amin(pixseries[i,j,:])
                    fmax = amax(pixseries[i,j,:])
                except:
                    ugh = 1
                xmin = tmin - (tmax - tmin) / 40
                xmax = tmax + (tmax - tmin) / 40
                ymin = fmin - (fmax - fmin) / 20
                ymax = fmax + (fmax - fmin) / 20
                if kepstat.bitInBitmap(maskimg[i,j],2):
                    pylab.axes([0.06+float(j)*dx,0.05+i*dy,dx,dy],axisbg='lightslategray')
                elif maskimg[i,j] == 0:
                    pylab.axes([0.06+float(j)*dx,0.05+i*dy,dx,dy],axisbg='black')
                else:
                    pylab.axes([0.06+float(j)*dx,0.05+i*dy,dx,dy])
                if j == int(xdim / 2) and i == 0:
                    pylab.setp(pylab.gca(),xticklabels=[],yticklabels=[])
                elif j == 0 and i == int(ydim / 2):
                    pylab.setp(pylab.gca(),xticklabels=[],yticklabels=[])
                else:
                    pylab.setp(pylab.gca(),xticklabels=[],yticklabels=[])
                ptime = time * 1.0
                ptime = numpy.insert(ptime,[0],ptime[0])
                ptime = numpy.append(ptime,ptime[-1])
                pflux = pixseries[i,j,:] * 1.0
                pflux = numpy.insert(pflux,[0],-1000.0)
                pflux = numpy.append(pflux,-1000.0)
                pylab.plot(time,pixseries[i,j,:],color='#0000ff',linestyle='-',linewidth=0.5)
                if not kepstat.bitInBitmap(maskimg[i,j],2):
                    pylab.fill(ptime,pflux,fc='lightslategray',linewidth=0.0,alpha=1.0)
                pylab.fill(ptime,pflux,fc='#FFF380',linewidth=0.0,alpha=1.0)
                if 'loc' in plottype:
                    pylab.xlim(xmin,xmax)
                    pylab.ylim(ymin,ymax)
                if 'glob' in plottype:
                    pylab.xlim(xmin,xmax)
                    pylab.ylim(1.0e-10,numpy.nanmax(pixseries) * 1.05)
                if 'full' in plottype:
                    pylab.xlim(xmin,xmax)
                    pylab.ylim(1.0e-10,ymax * 1.05)

# render plot

        if cmdLine: 
            pylab.show()
        else: 
            pylab.ion()
            pylab.plot([])
            pylab.ioff()	
        if plotfile.lower() != 'none':
            pylab.savefig(plotfile)

# stop time

    if status == 0:
        kepmsg.clock('KEPPIXSERIES ended at',logfile,verbose)

    return
Esempio n. 5
0
def keppixseries(infile,
                 outfile,
                 plotfile,
                 plottype,
                 filter,
                 function,
                 cutoff,
                 clobber,
                 verbose,
                 logfile,
                 status,
                 cmdLine=False):

    # input arguments

    status = 0
    seterr(all="ignore")

    # log the call

    hashline = '----------------------------------------------------------------------------'
    kepmsg.log(logfile, hashline, verbose)
    call = 'KEPPIXSERIES -- '
    call += 'infile=' + infile + ' '
    call += 'outfile=' + outfile + ' '
    call += 'plotfile=' + plotfile + ' '
    call += 'plottype=' + plottype + ' '
    filt = 'n'
    if (filter): filt = 'y'
    call += 'filter=' + filt + ' '
    call += 'function=' + function + ' '
    call += 'cutoff=' + str(cutoff) + ' '
    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('KEPPIXSERIES 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 -- KEPPIXSERIES: ' + outfile + ' exists. Use --clobber'
        status = kepmsg.err(logfile, message, verbose)

# 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, qual, status = \
            kepio.readTPF(infile,'QUALITY',logfile,verbose)

# read mask defintion data from TPF file

    if status == 0:
        maskimg, pixcoord1, pixcoord2, status = kepio.readMaskDefinition(
            infile, logfile, verbose)

# print target data

    if status == 0:
        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 ''

# how many quality = 0 rows?

    if status == 0:
        npts = 0
        nrows = len(fluxpixels)
        for i in range(nrows):
            if qual[i] == 0 and \
                    numpy.isfinite(barytime[i]) and \
                    numpy.isfinite(fluxpixels[i,ydim*xdim/2]):
                npts += 1
        time = empty((npts))
        timecorr = empty((npts))
        cadenceno = empty((npts))
        quality = empty((npts))
        pixseries = empty((ydim, xdim, npts))
        errseries = empty((ydim, xdim, npts))

# construct output light curves

    if status == 0:
        np = 0
        for i in range(ydim):
            for j in range(xdim):
                npts = 0
                for k in range(nrows):
                    if qual[k] == 0 and \
                    numpy.isfinite(barytime[k]) and \
                    numpy.isfinite(fluxpixels[k,ydim*xdim/2]):
                        time[npts] = barytime[k]
                        timecorr[npts] = tcorr[k]
                        cadenceno[npts] = cadno[k]
                        quality[npts] = qual[k]
                        pixseries[i, j, npts] = fluxpixels[k, np]
                        errseries[i, j, npts] = errpixels[k, np]
                        npts += 1
                np += 1

# define data sampling

    if status == 0 and filter:
        tpf, status = kepio.openfits(infile, 'readonly', logfile, verbose)
    if status == 0 and filter:
        cadence, status = kepkey.cadence(tpf[1], infile, logfile, verbose)
        tr = 1.0 / (cadence / 86400)
        timescale = 1.0 / (cutoff / tr)

# define convolution function

    if status == 0 and filter:
        if function == 'boxcar':
            filtfunc = numpy.ones(numpy.ceil(timescale))
        elif function == 'gauss':
            timescale /= 2
            dx = numpy.ceil(timescale * 10 + 1)
            filtfunc = kepfunc.gauss()
            filtfunc = filtfunc([1.0, dx / 2 - 1.0, timescale],
                                linspace(0, dx - 1, dx))
        elif function == 'sinc':
            dx = numpy.ceil(timescale * 12 + 1)
            fx = linspace(0, dx - 1, dx)
            fx = fx - dx / 2 + 0.5
            fx /= timescale
            filtfunc = numpy.sinc(fx)
        filtfunc /= numpy.sum(filtfunc)

# pad time series at both ends with noise model

    if status == 0 and filter:
        for i in range(ydim):
            for j in range(xdim):
                ave, sigma = kepstat.stdev(pixseries[i, j, :len(filtfunc)])
                padded = numpy.append(kepstat.randarray(numpy.ones(len(filtfunc)) * ave, \
                                                            numpy.ones(len(filtfunc)) * sigma), pixseries[i,j,:])
                ave, sigma = kepstat.stdev(pixseries[i, j, -len(filtfunc):])
                padded = numpy.append(padded, kepstat.randarray(numpy.ones(len(filtfunc)) * ave, \
                                                                    numpy.ones(len(filtfunc)) * sigma))

                # convolve data

                if status == 0:
                    convolved = convolve(padded, filtfunc, 'same')

# remove padding from the output array

                if status == 0:
                    outdata = convolved[len(filtfunc):-len(filtfunc)]

# subtract low frequencies

                if status == 0:
                    outmedian = median(outdata)
                    pixseries[i,
                              j, :] = pixseries[i, j, :] - outdata + outmedian

# construct output file

    if status == 0 and ydim * xdim < 1000:
        instruct, status = kepio.openfits(infile, 'readonly', logfile, verbose)
        status = kepkey.history(call, instruct[0], outfile, logfile, verbose)
        hdulist = HDUList(instruct[0])
        cols = []
        cols.append(
            Column(name='TIME',
                   format='D',
                   unit='BJD - 2454833',
                   disp='D12.7',
                   array=time))
        cols.append(
            Column(name='TIMECORR',
                   format='E',
                   unit='d',
                   disp='E13.6',
                   array=timecorr))
        cols.append(
            Column(name='CADENCENO', format='J', disp='I10', array=cadenceno))
        cols.append(Column(name='QUALITY', format='J', array=quality))
        for i in range(ydim):
            for j in range(xdim):
                colname = 'COL%d_ROW%d' % (i + column, j + row)
                cols.append(
                    Column(name=colname,
                           format='E',
                           disp='E13.6',
                           array=pixseries[i, j, :]))
        hdu1 = new_table(ColDefs(cols))
        try:
            hdu1.header.update('INHERIT', True, 'inherit the primary header')
        except:
            status = 0
        try:
            hdu1.header.update('EXTNAME', 'PIXELSERIES', 'name of extension')
        except:
            status = 0
        try:
            hdu1.header.update(
                'EXTVER', instruct[1].header['EXTVER'],
                'extension version number (not format version)')
        except:
            status = 0
        try:
            hdu1.header.update('TELESCOP', instruct[1].header['TELESCOP'],
                               'telescope')
        except:
            status = 0
        try:
            hdu1.header.update('INSTRUME', instruct[1].header['INSTRUME'],
                               'detector type')
        except:
            status = 0
        try:
            hdu1.header.update('OBJECT', instruct[1].header['OBJECT'],
                               'string version of KEPLERID')
        except:
            status = 0
        try:
            hdu1.header.update('KEPLERID', instruct[1].header['KEPLERID'],
                               'unique Kepler target identifier')
        except:
            status = 0
        try:
            hdu1.header.update('RADESYS', instruct[1].header['RADESYS'],
                               'reference frame of celestial coordinates')
        except:
            status = 0
        try:
            hdu1.header.update('RA_OBJ', instruct[1].header['RA_OBJ'],
                               '[deg] right ascension from KIC')
        except:
            status = 0
        try:
            hdu1.header.update('DEC_OBJ', instruct[1].header['DEC_OBJ'],
                               '[deg] declination from KIC')
        except:
            status = 0
        try:
            hdu1.header.update('EQUINOX', instruct[1].header['EQUINOX'],
                               'equinox of celestial coordinate system')
        except:
            status = 0
        try:
            hdu1.header.update('TIMEREF', instruct[1].header['TIMEREF'],
                               'barycentric correction applied to times')
        except:
            status = 0
        try:
            hdu1.header.update('TASSIGN', instruct[1].header['TASSIGN'],
                               'where time is assigned')
        except:
            status = 0
        try:
            hdu1.header.update('TIMESYS', instruct[1].header['TIMESYS'],
                               'time system is barycentric JD')
        except:
            status = 0
        try:
            hdu1.header.update('BJDREFI', instruct[1].header['BJDREFI'],
                               'integer part of BJD reference date')
        except:
            status = 0
        try:
            hdu1.header.update('BJDREFF', instruct[1].header['BJDREFF'],
                               'fraction of the day in BJD reference date')
        except:
            status = 0
        try:
            hdu1.header.update('TIMEUNIT', instruct[1].header['TIMEUNIT'],
                               'time unit for TIME, TSTART and TSTOP')
        except:
            status = 0
        try:
            hdu1.header.update('TSTART', instruct[1].header['TSTART'],
                               'observation start time in BJD-BJDREF')
        except:
            status = 0
        try:
            hdu1.header.update('TSTOP', instruct[1].header['TSTOP'],
                               'observation stop time in BJD-BJDREF')
        except:
            status = 0
        try:
            hdu1.header.update('LC_START', instruct[1].header['LC_START'],
                               'mid point of first cadence in MJD')
        except:
            status = 0
        try:
            hdu1.header.update('LC_END', instruct[1].header['LC_END'],
                               'mid point of last cadence in MJD')
        except:
            status = 0
        try:
            hdu1.header.update('TELAPSE', instruct[1].header['TELAPSE'],
                               '[d] TSTOP - TSTART')
        except:
            status = 0
        try:
            hdu1.header.update('LIVETIME', instruct[1].header['LIVETIME'],
                               '[d] TELAPSE multiplied by DEADC')
        except:
            status = 0
        try:
            hdu1.header.update('EXPOSURE', instruct[1].header['EXPOSURE'],
                               '[d] time on source')
        except:
            status = 0
        try:
            hdu1.header.update('DEADC', instruct[1].header['DEADC'],
                               'deadtime correction')
        except:
            status = 0
        try:
            hdu1.header.update('TIMEPIXR', instruct[1].header['TIMEPIXR'],
                               'bin time beginning=0 middle=0.5 end=1')
        except:
            status = 0
        try:
            hdu1.header.update('TIERRELA', instruct[1].header['TIERRELA'],
                               '[d] relative time error')
        except:
            status = 0
        try:
            hdu1.header.update('TIERABSO', instruct[1].header['TIERABSO'],
                               '[d] absolute time error')
        except:
            status = 0
        try:
            hdu1.header.update('INT_TIME', instruct[1].header['INT_TIME'],
                               '[s] photon accumulation time per frame')
        except:
            status = 0
        try:
            hdu1.header.update('READTIME', instruct[1].header['READTIME'],
                               '[s] readout time per frame')
        except:
            status = 0
        try:
            hdu1.header.update('FRAMETIM', instruct[1].header['FRAMETIM'],
                               '[s] frame time (INT_TIME + READTIME)')
        except:
            status = 0
        try:
            hdu1.header.update('NUM_FRM', instruct[1].header['NUM_FRM'],
                               'number of frames per time stamp')
        except:
            status = 0
        try:
            hdu1.header.update('TIMEDEL', instruct[1].header['TIMEDEL'],
                               '[d] time resolution of data')
        except:
            status = 0
        try:
            hdu1.header.update('DATE-OBS', instruct[1].header['DATE-OBS'],
                               'TSTART as UTC calendar date')
        except:
            status = 0
        try:
            hdu1.header.update('DATE-END', instruct[1].header['DATE-END'],
                               'TSTOP as UTC calendar date')
        except:
            status = 0
        try:
            hdu1.header.update('BACKAPP', instruct[1].header['BACKAPP'],
                               'background is subtracted')
        except:
            status = 0
        try:
            hdu1.header.update('DEADAPP', instruct[1].header['DEADAPP'],
                               'deadtime applied')
        except:
            status = 0
        try:
            hdu1.header.update('VIGNAPP', instruct[1].header['VIGNAPP'],
                               'vignetting or collimator correction applied')
        except:
            status = 0
        try:
            hdu1.header.update('GAIN', instruct[1].header['GAIN'],
                               '[electrons/count] channel gain')
        except:
            status = 0
        try:
            hdu1.header.update('READNOIS', instruct[1].header['READNOIS'],
                               '[electrons] read noise')
        except:
            status = 0
        try:
            hdu1.header.update('NREADOUT', instruct[1].header['NREADOUT'],
                               'number of read per cadence')
        except:
            status = 0
        try:
            hdu1.header.update('TIMSLICE', instruct[1].header['TIMSLICE'],
                               'time-slice readout sequence section')
        except:
            status = 0
        try:
            hdu1.header.update('MEANBLCK', instruct[1].header['MEANBLCK'],
                               '[count] FSW mean black level')
        except:
            status = 0
        hdulist.append(hdu1)
        hdulist.writeto(outfile)
        status = kepkey.new('EXTNAME', 'APERTURE', 'name of extension',
                            instruct[2], outfile, logfile, verbose)
        pyfits.append(outfile, instruct[2].data, instruct[2].header)
        status = kepio.closefits(instruct, logfile, verbose)
    else:
        message = 'WARNING -- KEPPIXSERIES: output FITS file requires > 999 columns. Non-compliant with FITS convention.'

        kepmsg.warn(logfile, message)

# plot style

    if status == 0:
        try:
            params = {
                'backend': 'png',
                'axes.linewidth': 2.0,
                'axes.labelsize': 32,
                'axes.font': 'sans-serif',
                'axes.fontweight': 'bold',
                'text.fontsize': 8,
                'legend.fontsize': 8,
                'xtick.labelsize': 12,
                'ytick.labelsize': 12
            }
            pylab.rcParams.update(params)
        except:
            pass

# plot pixel array

    fmin = 1.0e33
    fmax = -1.033
    if status == 0:
        pylab.figure(num=None, figsize=[12, 12])
        pylab.clf()
        dx = 0.93 / xdim
        dy = 0.94 / ydim
        ax = pylab.axes([0.06, 0.05, 0.93, 0.94])
        pylab.gca().xaxis.set_major_formatter(
            pylab.ScalarFormatter(useOffset=False))
        pylab.gca().yaxis.set_major_formatter(
            pylab.ScalarFormatter(useOffset=False))
        pylab.gca().xaxis.set_major_locator(
            matplotlib.ticker.MaxNLocator(integer=True))
        pylab.gca().yaxis.set_major_locator(
            matplotlib.ticker.MaxNLocator(integer=True))
        labels = ax.get_yticklabels()
        setp(labels, 'rotation', 90, fontsize=12)
        pylab.xlim(numpy.min(pixcoord1) - 0.5, numpy.max(pixcoord1) + 0.5)
        pylab.ylim(numpy.min(pixcoord2) - 0.5, numpy.max(pixcoord2) + 0.5)
        pylab.xlabel('time', {'color': 'k'})
        pylab.ylabel('arbitrary flux', {'color': 'k'})
        for i in range(ydim):
            for j in range(xdim):
                tmin = amin(time)
                tmax = amax(time)
                try:
                    numpy.isfinite(amin(pixseries[i, j, :]))
                    numpy.isfinite(amin(pixseries[i, j, :]))
                    fmin = amin(pixseries[i, j, :])
                    fmax = amax(pixseries[i, j, :])
                except:
                    ugh = 1
                xmin = tmin - (tmax - tmin) / 40
                xmax = tmax + (tmax - tmin) / 40
                ymin = fmin - (fmax - fmin) / 20
                ymax = fmax + (fmax - fmin) / 20
                if kepstat.bitInBitmap(maskimg[i, j], 2):
                    pylab.axes([0.06 + float(j) * dx, 0.05 + i * dy, dx, dy],
                               axisbg='lightslategray')
                elif maskimg[i, j] == 0:
                    pylab.axes([0.06 + float(j) * dx, 0.05 + i * dy, dx, dy],
                               axisbg='black')
                else:
                    pylab.axes([0.06 + float(j) * dx, 0.05 + i * dy, dx, dy])
                if j == int(xdim / 2) and i == 0:
                    pylab.setp(pylab.gca(), xticklabels=[], yticklabels=[])
                elif j == 0 and i == int(ydim / 2):
                    pylab.setp(pylab.gca(), xticklabels=[], yticklabels=[])
                else:
                    pylab.setp(pylab.gca(), xticklabels=[], yticklabels=[])
                ptime = time * 1.0
                ptime = numpy.insert(ptime, [0], ptime[0])
                ptime = numpy.append(ptime, ptime[-1])
                pflux = pixseries[i, j, :] * 1.0
                pflux = numpy.insert(pflux, [0], -1000.0)
                pflux = numpy.append(pflux, -1000.0)
                pylab.plot(time,
                           pixseries[i, j, :],
                           color='#0000ff',
                           linestyle='-',
                           linewidth=0.5)
                if not kepstat.bitInBitmap(maskimg[i, j], 2):
                    pylab.fill(ptime,
                               pflux,
                               fc='lightslategray',
                               linewidth=0.0,
                               alpha=1.0)
                pylab.fill(ptime,
                           pflux,
                           fc='#FFF380',
                           linewidth=0.0,
                           alpha=1.0)
                if 'loc' in plottype:
                    pylab.xlim(xmin, xmax)
                    pylab.ylim(ymin, ymax)
                if 'glob' in plottype:
                    pylab.xlim(xmin, xmax)
                    pylab.ylim(1.0e-10, numpy.nanmax(pixseries) * 1.05)
                if 'full' in plottype:
                    pylab.xlim(xmin, xmax)
                    pylab.ylim(1.0e-10, ymax * 1.05)

# render plot

        if cmdLine:
            pylab.show()
        else:
            pylab.ion()
            pylab.plot([])
            pylab.ioff()
        if plotfile.lower() != 'none':
            pylab.savefig(plotfile)

# stop time

    if status == 0:
        kepmsg.clock('KEPPIXSERIES ended at', logfile, verbose)

    return
Esempio n. 6
0
def PrfBorders(maskimg, xdim, ydim, pixcoord1, pixcoord2, bit, lcolor, lstyle,
               lwidth):

    for i in range(1, ydim):
        for j in range(1, xdim):
            if kepstat.bitInBitmap(
                    maskimg[i, j],
                    bit) and not kepstat.bitInBitmap(maskimg[i - 1, j], bit):
                x = array([pixcoord1[j - 1, i], pixcoord1[j, i]]) + 0.5
                y = array([pixcoord2[j, i], pixcoord2[j, i]]) - 0.5
                pylab.plot(x * 50,
                           y * 50,
                           color=lcolor,
                           linestyle=lstyle,
                           linewidth=lwidth)
            if not kepstat.bitInBitmap(maskimg[i, j],
                                       bit) and kepstat.bitInBitmap(
                                           maskimg[i - 1, j], bit):
                x = array([pixcoord1[j - 1, i], pixcoord1[j, i]]) + 0.5
                y = array([pixcoord2[j, i], pixcoord2[j, i]]) - 0.5
                pylab.plot(x * 50,
                           y * 50,
                           color=lcolor,
                           linestyle=lstyle,
                           linewidth=lwidth)
            if kepstat.bitInBitmap(
                    maskimg[i, j],
                    bit) and not kepstat.bitInBitmap(maskimg[i, j - 1], bit):
                x = array([pixcoord1[j, i], pixcoord1[j, i]]) - 0.5
                y = array([pixcoord2[j, i - 1], pixcoord2[j, i]]) + 0.5
                pylab.plot(x * 50,
                           y * 50,
                           color=lcolor,
                           linestyle=lstyle,
                           linewidth=lwidth)
            if not kepstat.bitInBitmap(maskimg[i, j],
                                       bit) and kepstat.bitInBitmap(
                                           maskimg[i, j - 1], bit):
                x = array([pixcoord1[j, i], pixcoord1[j, i]]) - 0.5
                y = array([pixcoord2[j, i - 1], pixcoord2[j, i]]) + 0.5
                pylab.plot(x * 50,
                           y * 50,
                           color=lcolor,
                           linestyle=lstyle,
                           linewidth=lwidth)

# corner cases

    for j in range(ydim):
        try:
            if kepstat.bitInBitmap(
                    maskimg[j, 0],
                    bit) and not kepstat.bitInBitmap(maskimg[j - 1, 0], bit):
                x = array([pixcoord1[0, j], pixcoord1[1, j]]) - 0.5
                y = array([pixcoord2[0, j], pixcoord2[0, j]]) - 0.5
                pylab.plot(x,
                           y,
                           color=lcolor,
                           linestyle=lstyle,
                           linewidth=lwidth)
        except:
            pass
        try:
            if not kepstat.bitInBitmap(maskimg[j + 1, 0],
                                       bit) and kepstat.bitInBitmap(
                                           maskimg[j, 0], bit):
                x = array([pixcoord1[0, j], pixcoord1[1, j]]) - 0.5
                y = array([pixcoord2[0, j], pixcoord2[0, j]]) + 0.5
                pylab.plot(x,
                           y,
                           color=lcolor,
                           linestyle=lstyle,
                           linewidth=lwidth)
        except:
            pass
        if kepstat.bitInBitmap(maskimg[j, 0], bit):
            x = array([pixcoord1[0, j], pixcoord1[0, j]]) - 0.5
            try:
                y = array([pixcoord2[0, j], pixcoord2[0, j + 1]]) - 0.5
            except:
                y = array([pixcoord2[0, j - 1], pixcoord2[0, j]]) + 0.5
            pylab.plot(x, y, color=lcolor, linestyle=lstyle, linewidth=lwidth)
        if kepstat.bitInBitmap(maskimg[j, xdim - 1], bit):
            x = array([pixcoord1[xdim - 1, j], pixcoord1[xdim - 1, j]]) + 0.5
            try:
                y = array([pixcoord2[xdim - 1, j], pixcoord2[xdim - 1, j + 1]
                           ]) - 0.5
            except:
                y = array([pixcoord2[xdim - 1, j - 1], pixcoord2[xdim - 1, j]
                           ]) + 0.5
            pylab.plot(x, y, color=lcolor, linestyle=lstyle, linewidth=lwidth)
    for i in range(xdim):
        try:
            if kepstat.bitInBitmap(
                    maskimg[0, i],
                    bit) and not kepstat.bitInBitmap(maskimg[0, i - 1], bit):
                x = array([pixcoord1[i, 0], pixcoord1[i, 0]]) - 0.5
                y = array([pixcoord2[i, 0], pixcoord2[i, 1]]) - 0.5
                pylab.plot(x,
                           y,
                           color=lcolor,
                           linestyle=lstyle,
                           linewidth=lwidth)
        except:
            pass
        try:
            if not kepstat.bitInBitmap(maskimg[0, i + 1],
                                       bit) and kepstat.bitInBitmap(
                                           maskimg[0, i], bit):
                x = array([pixcoord1[i, 0], pixcoord1[i, 0]]) + 0.5
                y = array([pixcoord2[i, 0], pixcoord2[i, 1]]) - 0.5
                pylab.plot(x,
                           y,
                           color=lcolor,
                           linestyle=lstyle,
                           linewidth=lwidth)
        except:
            pass
        if kepstat.bitInBitmap(maskimg[0, i], bit):
            try:
                x = array([pixcoord1[i, 0], pixcoord1[i + 1, 0]]) - 0.5
            except:
                x = array([pixcoord1[i - 1, 0], pixcoord1[i, 0]]) + 0.5
            y = array([pixcoord2[i, 0], pixcoord2[i, 0]]) - 0.5
            pylab.plot(x, y, color=lcolor, linestyle=lstyle, linewidth=lwidth)
        if kepstat.bitInBitmap(maskimg[ydim - 1, i], bit):
            try:
                x = array([pixcoord1[i, ydim - 1], pixcoord1[i + 1, ydim - 1]
                           ]) - 0.5
            except:
                x = array([pixcoord1[i - 1, ydim - 1], pixcoord1[i, ydim - 1]
                           ]) - 0.5
            y = array([pixcoord2[i, ydim - 1], pixcoord2[i, ydim - 1]]) + 0.5
            pylab.plot(x, y, color=lcolor, linestyle=lstyle, linewidth=lwidth)

    if kepstat.bitInBitmap(maskimg[ydim - 1, xdim - 1], bit):
        x = array([
            pixcoord1[xdim - 2, ydim - 1], pixcoord1[xdim - 1, ydim - 1]
        ]) + 0.5
        y = array([
            pixcoord2[xdim - 1, ydim - 1], pixcoord2[xdim - 1, ydim - 1]
        ]) + 0.5
        pylab.plot(x, y, color=lcolor, linestyle=lstyle, linewidth=lwidth)

    if kepstat.bitInBitmap(maskimg[0, xdim - 1], bit):
        x = array([pixcoord1[xdim - 1, 0], pixcoord1[xdim - 1, 0]]) + 0.5
        y = array([pixcoord2[xdim - 1, 0], pixcoord2[xdim - 1, 1]]) - 0.5
        pylab.plot(x, y, color=lcolor, linestyle=lstyle, linewidth=lwidth)

    return
Esempio n. 7
0
def kepprf(infile,
           columns,
           rows,
           fluxes,
           rownum=0,
           border=0,
           background=0,
           focus=0,
           prfdir='../KeplerPRF',
           xtol=1.e-6,
           ftol=1.e-6,
           imscale='linear',
           cmap='YlOrBr',
           lcolor='k',
           acolor='b',
           logfile='kepcrowd.log',
           CrowdTPF=np.nan,
           srcinfo=None,
           **kwargs):

    # log the call
    hashline = '----------------------------------------------------------------------------'
    kepmsg.log(logfile, hashline, True)
    call = 'KEPPRF -- '
    call += 'infile=' + infile + ' '
    call += 'rownum=' + str(rownum) + ' '
    call += 'columns=' + columns + ' '
    call += 'rows=' + rows + ' '
    call += 'fluxes=' + fluxes + ' '
    call += 'border=' + str(border) + ' '
    bground = 'n'
    if (background): bground = 'y'
    call += 'background=' + bground + ' '
    focs = 'n'
    if (focus): focs = 'y'
    call += 'focus=' + focs + ' '
    call += 'prfdir=' + prfdir + ' '
    call += 'xtol=' + str(xtol) + ' '
    call += 'ftol=' + str(xtol) + ' '
    call += 'logfile=' + logfile
    kepmsg.log(logfile, call + '\n', True)

    guess = []
    try:
        f = fluxes.strip().split(',')
        x = columns.strip().split(',')
        y = rows.strip().split(',')
        for i in range(len(f)):
            f[i] = float(f[i])
    except:
        f = fluxes
        x = columns
        y = rows

    nsrc = len(f)
    for i in range(nsrc):
        try:
            guess.append(float(f[i]))
        except:
            message = 'ERROR -- KEPPRF: Fluxes must be floating point numbers'
            kepmsg.err(logfile, message, True)
            return None

    if len(x) != nsrc or len(y) != nsrc:
        message = 'ERROR -- KEPFIT:FITMULTIPRF: Guesses for rows, columns and '
        message += 'fluxes must have the same number of sources'
        kepmsg.err(logfile, message, True)
        return None

    for i in range(nsrc):
        try:
            guess.append(float(x[i]))
        except:
            message = 'ERROR -- KEPPRF: Columns must be floating point numbers'
            kepmsg.err(logfile, message, True)
            return None

    for i in range(nsrc):
        try:
            guess.append(float(y[i]))
        except:
            message = 'ERROR -- KEPPRF: Rows must be floating point numbers'
            kepmsg.err(logfile, message, True)
            return None

    if background:
        if border == 0:
            guess.append(0.0)
        else:
            for i in range((border + 1) * 2):
                guess.append(0.0)

    if focus:
        guess.append(1.0)
        guess.append(1.0)
        guess.append(0.0)

    # open TPF FITS file
    try:
        kepid, channel, skygroup, module, output, quarter, season, \
            ra, dec, column, row, kepmag, xdim, ydim, barytime, status = \
            kepio.readTPF(infile,'TIME',logfile,True)
    except:
        message = 'ERROR -- KEPPRF: is %s a Target Pixel File? ' % infile
        kepmsg.err(logfile, message, True)
        return None

    kepid, channel, skygroup, module, output, quarter, season, \
        ra, dec, column, row, kepmag, xdim, ydim, tcorr, status = \
        kepio.readTPF(infile,'TIMECORR',logfile,True)

    kepid, channel, skygroup, module, output, quarter, season, \
        ra, dec, column, row, kepmag, xdim, ydim, cadno, status = \
        kepio.readTPF(infile,'CADENCENO',logfile,True)

    kepid, channel, skygroup, module, output, quarter, season, \
        ra, dec, column, row, kepmag, xdim, ydim, fluxpixels, status = \
        kepio.readTPF(infile,'FLUX',logfile,True)

    kepid, channel, skygroup, module, output, quarter, season, \
        ra, dec, column, row, kepmag, xdim, ydim, errpixels, status = \
        kepio.readTPF(infile,'FLUX_ERR',logfile,True)

    kepid, channel, skygroup, module, output, quarter, season, \
        ra, dec, column, row, kepmag, xdim, ydim, qual, status = \
        kepio.readTPF(infile,'QUALITY',logfile,True)

    # read mask defintion data from TPF file
    maskimg, pixcoord1, pixcoord2, status = kepio.readMaskDefinition(
        infile, logfile, True)
    npix = np.size(np.nonzero(maskimg)[0])

    print('')
    print('      KepID: %s' % kepid)
    print('        BJD: %.2f' % (barytime[rownum - 1] + 2454833.0))
    print(' RA (J2000): %s' % ra)
    print('Dec (J2000):  %s' % dec)
    print('     KepMag:  %s' % kepmag)
    print('   SkyGroup:   %2s' % skygroup)
    print('     Season:   %2s' % str(season))
    print('    Channel:   %2s' % channel)
    print('     Module:   %2s' % module)
    print('     Output:    %1s' % output)
    print('')

    # is this a good row with finite timestamp and pixels?
    if not np.isfinite(barytime[rownum - 1]) or np.nansum(
            fluxpixels[rownum - 1, :]) == np.nan:
        message = 'ERROR -- KEPFIELD: Row ' + str(
            rownum) + ' is a bad quality timestamp'
        status = kepmsg.err(logfile, message, True)

    # construct input pixel image
    flux = fluxpixels[rownum - 1, :]
    ferr = errpixels[rownum - 1, :]
    DATx = np.arange(column, column + xdim)
    DATy = np.arange(row, row + ydim)

    # image scale and intensity limits of pixel data
    n = 0
    DATimg = np.empty((ydim, xdim))
    ERRimg = np.empty((ydim, xdim))
    for i in range(ydim):
        for j in range(xdim):
            DATimg[i, j] = flux[n]
            ERRimg[i, j] = ferr[n]
            n += 1

    # determine suitable PRF calibration file
    if int(module) < 10:
        prefix = 'kplr0'
    else:
        prefix = 'kplr'
    prfglob = prfdir + '/' + prefix + str(module) + '.' + str(
        output) + '*' + '_prf.fits'
    try:
        prffile = glob.glob(prfglob)[0]
    except:
        message = 'ERROR -- KEPPRF: No PRF file found in ' + prfdir
        kepmsg.err(logfile, message, True)
        return None

    # read PRF images
    prfn = [0, 0, 0, 0, 0]
    crpix1p = np.zeros((5), dtype='float32')
    crpix2p = np.zeros((5), dtype='float32')
    crval1p = np.zeros((5), dtype='float32')
    crval2p = np.zeros((5), dtype='float32')
    cdelt1p = np.zeros((5), dtype='float32')
    cdelt2p = np.zeros((5), dtype='float32')
    for i in range(5):
        prfn[i], crpix1p[i], crpix2p[i], crval1p[i], crval2p[i], cdelt1p[i], cdelt2p[i], status \
            = kepio.readPRFimage(prffile,i+1,logfile,True)
    prfn = np.array(prfn)
    PRFx = np.arange(0.5, np.shape(prfn[0])[1] + 0.5)
    PRFy = np.arange(0.5, np.shape(prfn[0])[0] + 0.5)
    PRFx = (PRFx - np.size(PRFx) / 2) * cdelt1p[0]
    PRFy = (PRFy - np.size(PRFy) / 2) * cdelt2p[0]

    # interpolate the calibrated PRF shape to the target position
    prf = np.zeros(np.shape(prfn[0]), dtype='float32')
    prfWeight = np.zeros((5), dtype='float32')
    for i in range(5):
        prfWeight[i] = np.sqrt((column - crval1p[i])**2 +
                               (row - crval2p[i])**2)
        if prfWeight[i] == 0.0:
            prfWeight[i] = 1.0e-6
        prf = prf + prfn[i] / prfWeight[i]
    prf = prf / np.nansum(prf) / cdelt1p[0] / cdelt2p[0]

    # location of the data image centered on the PRF image (in PRF pixel units)
    prfDimY = int(ydim / cdelt1p[0])
    prfDimX = int(xdim / cdelt2p[0])
    PRFy0 = (np.shape(prf)[0] - prfDimY) / 2
    PRFx0 = (np.shape(prf)[1] - prfDimX) / 2

    # interpolation function over the PRF
    splineInterpolation = scipy.interpolate.RectBivariateSpline(
        PRFx, PRFy, prf)

    # construct mesh for background model
    if background:
        bx = np.arange(1., float(xdim + 1))
        by = np.arange(1., float(ydim + 1))
        xx, yy = np.meshgrid(np.linspace(bx.min(), bx.max(), xdim),
                             np.linspace(by.min(), by.max(), ydim))

    # fit PRF model to pixel data
    start = time.time()
    if focus and background:
        args = (DATx, DATy, DATimg, ERRimg, nsrc, border, xx, yy,
                splineInterpolation, float(x[0]), float(y[0]))
        ans = fmin_powell(kepfunc.PRFwithFocusAndBackground,
                          guess,
                          args=args,
                          xtol=xtol,
                          ftol=ftol,
                          disp=False)
    elif focus and not background:
        args = (DATx, DATy, DATimg, ERRimg, nsrc, splineInterpolation,
                float(x[0]), float(y[0]))
        ans = fmin_powell(kepfunc.PRFwithFocus,
                          guess,
                          args=args,
                          xtol=xtol,
                          ftol=ftol,
                          disp=False)
    elif background and not focus:
        args = (DATx, DATy, DATimg, ERRimg, nsrc, border, xx, yy,
                splineInterpolation, float(x[0]), float(y[0]))
        ans = fmin_powell(kepfunc.PRFwithBackground,
                          guess,
                          args=args,
                          xtol=xtol,
                          ftol=ftol,
                          disp=False)
    else:
        args = (DATx, DATy, DATimg, ERRimg, nsrc, splineInterpolation,
                float(x[0]), float(y[0]))
        ans = fmin_powell(kepfunc.PRF,
                          guess,
                          args=args,
                          xtol=xtol,
                          ftol=ftol,
                          disp=False)
    kepmsg.log(logfile, 'Convergence time = %.2fs\n' % (time.time() - start),
               True)

    # pad the PRF data if the PRF array is smaller than the data array
    flux = []
    OBJx = []
    OBJy = []
    PRFmod = np.zeros((prfDimY, prfDimX))
    if PRFy0 < 0 or PRFx0 < 0.0:
        PRFmod = np.zeros((prfDimY, prfDimX))
        superPRF = np.zeros((prfDimY + 1, prfDimX + 1))
        superPRF[np.abs(PRFy0):np.abs(PRFy0) + np.shape(prf)[0],
                 np.abs(PRFx0):np.abs(PRFx0) + np.shape(prf)[1]] = prf
        prf = superPRF * 1.0
        PRFy0 = 0
        PRFx0 = 0

    # rotate the PRF model around its center
    if focus:
        angle = ans[-1]
        prf = rotate(prf, -angle, reshape=False, mode='nearest')

    # iterate through the sources in the best fit PSF model
    for i in range(nsrc):
        flux.append(ans[i])
        OBJx.append(ans[nsrc + i])
        OBJy.append(ans[nsrc * 2 + i])

        # calculate best-fit model
        y = (OBJy[i] - np.mean(DATy)) / cdelt1p[0]
        x = (OBJx[i] - np.mean(DATx)) / cdelt2p[0]
        prfTmp = shift(prf, [y, x], order=3, mode='constant')
        prfTmp = prfTmp[PRFy0:PRFy0 + prfDimY, PRFx0:PRFx0 + prfDimX]
        PRFmod = PRFmod + prfTmp * flux[i]
        wx = 1.0
        wy = 1.0
        angle = 0
        b = 0.0

        # write out best fit parameters
        txt = 'Flux = %10.2f e-/s ' % flux[i]
        txt += 'X = %9.4f pix ' % OBJx[i]
        txt += 'Y = %9.4f pix ' % OBJy[i]
        kepmsg.log(logfile, txt, True)

    if background:
        bterms = border + 1
        if bterms == 1:
            b = ans[nsrc * 3]
        else:
            bcoeff = np.array([
                ans[nsrc * 3:nsrc * 3 + bterms],
                ans[nsrc * 3 + bterms:nsrc * 3 + bterms * 2]
            ])
            bkg = kepfunc.polyval2d(xx, yy, bcoeff)
            b = nanmean(bkg.reshape(bkg.size))
        txt = '\n   Mean background = %.2f e-/s' % b
        kepmsg.log(logfile, txt, True)
    if focus:
        wx = ans[-3]
        wy = ans[-2]
        angle = ans[-1]
        if not background: kepmsg.log(logfile, '', True)
        kepmsg.log(logfile, ' X/Y focus factors = %.3f/%.3f' % (wx, wy), True)
        kepmsg.log(logfile, 'PRF rotation angle = %.2f deg' % angle, True)

    # measure flux fraction and contamination

    # LUGER: This looks horribly bugged. ``PRFall`` is certainly NOT the sum of the all the sources.
    # Check out my comments in ``kepfunc.py``.

    PRFall = kepfunc.PRF2DET(flux, OBJx, OBJy, DATx, DATy, wx, wy, angle,
                             splineInterpolation)
    PRFone = kepfunc.PRF2DET([flux[0]], [OBJx[0]], [OBJy[0]], DATx, DATy, wx,
                             wy, angle, splineInterpolation)

    # LUGER: Add up contaminant fluxes
    PRFcont = np.zeros_like(PRFone)
    for ncont in range(1, len(flux)):
        PRFcont += kepfunc.PRF2DET([flux[ncont]], [OBJx[ncont]], [OBJy[ncont]],
                                   DATx, DATy, wx, wy, angle,
                                   splineInterpolation)
    PRFcont[np.where(PRFcont < 0)] = 0

    FluxInMaskAll = np.nansum(PRFall)
    FluxInMaskOne = np.nansum(PRFone)
    FluxInAperAll = 0.0
    FluxInAperOne = 0.0
    FluxInAperAllTrue = 0.0

    for i in range(1, ydim):
        for j in range(1, xdim):
            if kepstat.bitInBitmap(maskimg[i, j], 2):
                FluxInAperAll += PRFall[i, j]
                FluxInAperOne += PRFone[i, j]
                FluxInAperAllTrue += PRFone[i, j] + PRFcont[i, j]
    FluxFraction = FluxInAperOne / flux[0]
    try:
        Contamination = (FluxInAperAll - FluxInAperOne) / FluxInAperAll
    except:
        Contamination = 0.0

    # LUGER: Pixel crowding metrics
    Crowding = PRFone / (PRFone + PRFcont)
    Crowding[np.where(Crowding < 0)] = np.nan

    # LUGER: Optimal aperture crowding metric
    CrowdAper = FluxInAperOne / FluxInAperAllTrue

    kepmsg.log(
        logfile,
        '\n                Total flux in mask = %.2f e-/s' % FluxInMaskAll,
        True)
    kepmsg.log(
        logfile,
        '               Target flux in mask = %.2f e-/s' % FluxInMaskOne, True)
    kepmsg.log(
        logfile,
        '            Total flux in aperture = %.2f e-/s' % FluxInAperAll, True)
    kepmsg.log(
        logfile,
        '           Target flux in aperture = %.2f e-/s' % FluxInAperOne, True)
    kepmsg.log(
        logfile,
        '  Target flux fraction in aperture = %.2f%%' % (FluxFraction * 100.0),
        True)
    kepmsg.log(
        logfile, 'Contamination fraction in aperture = %.2f%%' %
        (Contamination * 100.0), True)
    kepmsg.log(logfile,
               '       Crowding metric in aperture = %.4f' % (CrowdAper), True)
    kepmsg.log(logfile,
               '          Crowding metric from TPF = %.4f' % (CrowdTPF), True)

    # constuct model PRF in detector coordinates
    PRFfit = PRFall + 0.0
    if background and bterms == 1:
        PRFfit = PRFall + b
    if background and bterms > 1:
        PRFfit = PRFall + bkg

    # calculate residual of DATA - FIT
    PRFres = DATimg - PRFfit
    FLUXres = np.nansum(PRFres) / npix

    # calculate the sum squared difference between data and model
    Pearson = np.abs(np.nansum(np.square(DATimg - PRFfit) / PRFfit))
    Chi2 = np.nansum(np.square(DATimg - PRFfit) / np.square(ERRimg))
    DegOfFreedom = npix - len(guess) - 1
    try:
        kepmsg.log(logfile, '\n       Residual flux = %.2f e-/s' % FLUXres,
                   True)
        kepmsg.log(
            logfile,
            'Pearson\'s chi^2 test = %d for %d dof' % (Pearson, DegOfFreedom),
            True)
    except:
        pass
    kepmsg.log(logfile,
               '          Chi^2 test = %d for %d dof' % (Chi2, DegOfFreedom),
               True)

    # image scale and intensity limits for plotting images
    imgdat_pl, zminfl, zmaxfl = kepplot.intScale2D(DATimg, imscale)
    imgprf_pl, zminpr, zmaxpr = kepplot.intScale2D(PRFmod, imscale)
    imgfit_pl, zminfi, zmaxfi = kepplot.intScale2D(PRFfit, imscale)
    imgres_pl, zminre, zmaxre = kepplot.intScale2D(PRFres, 'linear')
    if imscale == 'linear':
        zmaxpr *= 0.9
    elif imscale == 'logarithmic':
        zmaxpr = np.max(zmaxpr)
        zminpr = zmaxpr / 2

    # plot
    pl.figure(figsize=[12, 10])
    pl.clf()

    # data
    plotimage(imgdat_pl, zminfl, zmaxfl, 1, row, column, xdim, ydim, 0.07,
              0.58, 'observation', cmap, lcolor)
    pl.text(0.05,
            0.05,
            'CROWDSAP: %.4f' % CrowdTPF,
            horizontalalignment='left',
            verticalalignment='center',
            fontsize=18,
            fontweight=500,
            color=lcolor,
            transform=pl.gca().transAxes)
    kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 1, acolor, '--',
                    0.5)
    kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 2, acolor, '-',
                    3.0)

    # model
    plotimage(imgprf_pl, zminpr, zmaxpr, 2, row, column, xdim, ydim, 0.445,
              0.58, 'model', cmap, lcolor)
    pl.text(0.05,
            0.05,
            'Crowding: %.4f' % CrowdAper,
            horizontalalignment='left',
            verticalalignment='center',
            fontsize=18,
            fontweight=500,
            color=lcolor,
            transform=pl.gca().transAxes)
    for x, y in zip(OBJx, OBJy):
        pl.scatter(x, y, marker='x', color='w')
    kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 1, acolor, '--',
                    0.5)
    kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 2, acolor, '-',
                    3.0)

    if srcinfo is not None:
        kepid, sx, sy, kepmag = srcinfo
        for i in range(len(sx) - 1, -1, -1):
            if kepid[i] != 0 and kepmag[i] != 0.0:
                size = max(
                    np.array([
                        80.0, 80.0 +
                        (2.5**(18.0 - max(12.0, float(kepmag[i])))) * 250.0
                    ]))
                pl.scatter(sx[i],
                           sy[i],
                           s=size,
                           facecolors='g',
                           edgecolors='k',
                           alpha=0.1)
            else:
                pl.scatter(sx[i],
                           sy[i],
                           s=80,
                           facecolors='r',
                           edgecolors='k',
                           alpha=0.1)

    # binned model
    plotimage(imgfit_pl,
              zminfl,
              zmaxfl,
              3,
              row,
              column,
              xdim,
              ydim,
              0.07,
              0.18,
              'fit',
              cmap,
              lcolor,
              crowd=Crowding)
    kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 1, acolor, '--',
                    0.5)
    kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 2, acolor, '-',
                    3.0)

    # residuals
    reslim = max(np.abs(zminre), np.abs(zmaxre))
    plotimage(imgres_pl, -reslim, reslim, 4, row, column, xdim, ydim, 0.445,
              0.18, 'residual', 'coolwarm', lcolor)
    kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 1, acolor, '--',
                    0.5)
    kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 2, acolor, '-',
                    3.0)

    # plot data color bar
    barwin = pl.axes([0.84, 0.18, 0.03, 0.8])
    if imscale == 'linear':
        brange = np.arange(zminfl, zmaxfl, (zmaxfl - zminfl) / 1000)
    elif imscale == 'logarithmic':
        brange = np.arange(10.0**zminfl, 10.0**zmaxfl,
                           (10.0**zmaxfl - 10.0**zminfl) / 1000)
    elif imscale == 'squareroot':
        brange = np.arange(zminfl**2, zmaxfl**2,
                           (zmaxfl**2 - zminfl**2) / 1000)
    if imscale == 'linear':
        barimg = np.resize(brange, (1000, 1))
    elif imscale == 'logarithmic':
        barimg = np.log10(np.resize(brange, (1000, 1)))
    elif imscale == 'squareroot':
        barimg = np.sqrt(np.resize(brange, (1000, 1)))
    try:
        nrm = len(str(int(np.nanmax(brange)))) - 1
    except:
        nrm = 0
    brange = brange / 10**nrm
    pl.imshow(barimg,
              aspect='auto',
              interpolation='nearest',
              origin='lower',
              vmin=np.nanmin(barimg),
              vmax=np.nanmax(barimg),
              extent=(0.0, 1.0, brange[0], brange[-1]),
              cmap=cmap)
    barwin.yaxis.tick_right()
    barwin.yaxis.set_label_position('right')
    barwin.yaxis.set_major_locator(MaxNLocator(7))
    pl.gca().yaxis.set_major_formatter(pl.ScalarFormatter(useOffset=False))
    pl.gca().set_autoscale_on(False)
    pl.setp(pl.gca(), xticklabels=[], xticks=[])
    pl.ylabel('Flux (10$^%d$ e$^-$ s$^{-1}$)' % nrm)
    pl.setp(barwin.get_yticklabels(), 'rotation', 90)
    barwin.yaxis.set_major_formatter(FormatStrFormatter('%.1f'))

    # plot residual color bar
    barwin = pl.axes([0.07, 0.08, 0.75, 0.03])
    brange = np.arange(-reslim, reslim, reslim / 500)
    barimg = np.resize(brange, (1, 1000))
    pl.imshow(barimg,
              aspect='auto',
              interpolation='nearest',
              origin='lower',
              vmin=np.nanmin(barimg),
              vmax=np.nanmax(barimg),
              extent=(brange[0], brange[-1], 0.0, 1.0),
              cmap='coolwarm')
    barwin.xaxis.set_major_locator(MaxNLocator(7))
    pl.gca().xaxis.set_major_formatter(pl.ScalarFormatter(useOffset=False))
    pl.gca().set_autoscale_on(False)
    pl.setp(pl.gca(), yticklabels=[], yticks=[])
    pl.xlabel('Residuals (e$^-$ s$^{-1}$)')
    barwin.xaxis.set_major_formatter(FormatStrFormatter('%.1f'))

    # render plot
    pl.show(block=True)
    pl.close()

    # stop time
    kepmsg.clock('\nKEPPRF ended at', logfile, True)

    return Crowding
Esempio n. 8
0
def kepprf(
    infile,
    columns,
    rows,
    fluxes,
    rownum=0,
    border=0,
    background=0,
    focus=0,
    prfdir="../KeplerPRF",
    xtol=1.0e-6,
    ftol=1.0e-6,
    imscale="linear",
    cmap="YlOrBr",
    lcolor="k",
    acolor="b",
    logfile="kepcrowd.log",
    CrowdTPF=np.nan,
    srcinfo=None,
    **kwargs
):

    # log the call
    hashline = "----------------------------------------------------------------------------"
    kepmsg.log(logfile, hashline, True)
    call = "KEPPRF -- "
    call += "infile=" + infile + " "
    call += "rownum=" + str(rownum) + " "
    call += "columns=" + columns + " "
    call += "rows=" + rows + " "
    call += "fluxes=" + fluxes + " "
    call += "border=" + str(border) + " "
    bground = "n"
    if background:
        bground = "y"
    call += "background=" + bground + " "
    focs = "n"
    if focus:
        focs = "y"
    call += "focus=" + focs + " "
    call += "prfdir=" + prfdir + " "
    call += "xtol=" + str(xtol) + " "
    call += "ftol=" + str(xtol) + " "
    call += "logfile=" + logfile
    kepmsg.log(logfile, call + "\n", True)

    guess = []
    try:
        f = fluxes.strip().split(",")
        x = columns.strip().split(",")
        y = rows.strip().split(",")
        for i in range(len(f)):
            f[i] = float(f[i])
    except:
        f = fluxes
        x = columns
        y = rows

    nsrc = len(f)
    for i in range(nsrc):
        try:
            guess.append(float(f[i]))
        except:
            message = "ERROR -- KEPPRF: Fluxes must be floating point numbers"
            kepmsg.err(logfile, message, True)
            return None

    if len(x) != nsrc or len(y) != nsrc:
        message = "ERROR -- KEPFIT:FITMULTIPRF: Guesses for rows, columns and "
        message += "fluxes must have the same number of sources"
        kepmsg.err(logfile, message, True)
        return None

    for i in range(nsrc):
        try:
            guess.append(float(x[i]))
        except:
            message = "ERROR -- KEPPRF: Columns must be floating point numbers"
            kepmsg.err(logfile, message, True)
            return None

    for i in range(nsrc):
        try:
            guess.append(float(y[i]))
        except:
            message = "ERROR -- KEPPRF: Rows must be floating point numbers"
            kepmsg.err(logfile, message, True)
            return None

    if background:
        if border == 0:
            guess.append(0.0)
        else:
            for i in range((border + 1) * 2):
                guess.append(0.0)

    if focus:
        guess.append(1.0)
        guess.append(1.0)
        guess.append(0.0)

    # open TPF FITS file
    try:
        kepid, channel, skygroup, module, output, quarter, season, ra, dec, column, row, kepmag, xdim, ydim, barytime, status = kepio.readTPF(
            infile, "TIME", logfile, True
        )
    except:
        message = "ERROR -- KEPPRF: is %s a Target Pixel File? " % infile
        kepmsg.err(logfile, message, True)
        return None

    kepid, channel, skygroup, module, output, quarter, season, ra, dec, column, row, kepmag, xdim, ydim, tcorr, status = kepio.readTPF(
        infile, "TIMECORR", logfile, True
    )

    kepid, channel, skygroup, module, output, quarter, season, ra, dec, column, row, kepmag, xdim, ydim, cadno, status = kepio.readTPF(
        infile, "CADENCENO", logfile, True
    )

    kepid, channel, skygroup, module, output, quarter, season, ra, dec, column, row, kepmag, xdim, ydim, fluxpixels, status = kepio.readTPF(
        infile, "FLUX", logfile, True
    )

    kepid, channel, skygroup, module, output, quarter, season, ra, dec, column, row, kepmag, xdim, ydim, errpixels, status = kepio.readTPF(
        infile, "FLUX_ERR", logfile, True
    )

    kepid, channel, skygroup, module, output, quarter, season, ra, dec, column, row, kepmag, xdim, ydim, qual, status = kepio.readTPF(
        infile, "QUALITY", logfile, True
    )

    # read mask defintion data from TPF file
    maskimg, pixcoord1, pixcoord2, status = kepio.readMaskDefinition(infile, logfile, True)
    npix = np.size(np.nonzero(maskimg)[0])

    print("")
    print("      KepID: %s" % kepid)
    print("        BJD: %.2f" % (barytime[rownum - 1] + 2454833.0))
    print(" RA (J2000): %s" % ra)
    print("Dec (J2000):  %s" % dec)
    print("     KepMag:  %s" % kepmag)
    print("   SkyGroup:   %2s" % skygroup)
    print("     Season:   %2s" % str(season))
    print("    Channel:   %2s" % channel)
    print("     Module:   %2s" % module)
    print("     Output:    %1s" % output)
    print("")

    # is this a good row with finite timestamp and pixels?
    if not np.isfinite(barytime[rownum - 1]) or np.nansum(fluxpixels[rownum - 1, :]) == np.nan:
        message = "ERROR -- KEPFIELD: Row " + str(rownum) + " is a bad quality timestamp"
        status = kepmsg.err(logfile, message, True)

    # construct input pixel image
    flux = fluxpixels[rownum - 1, :]
    ferr = errpixels[rownum - 1, :]
    DATx = np.arange(column, column + xdim)
    DATy = np.arange(row, row + ydim)

    # image scale and intensity limits of pixel data
    n = 0
    DATimg = np.empty((ydim, xdim))
    ERRimg = np.empty((ydim, xdim))
    for i in range(ydim):
        for j in range(xdim):
            DATimg[i, j] = flux[n]
            ERRimg[i, j] = ferr[n]
            n += 1

    # determine suitable PRF calibration file
    if int(module) < 10:
        prefix = "kplr0"
    else:
        prefix = "kplr"
    prfglob = prfdir + "/" + prefix + str(module) + "." + str(output) + "*" + "_prf.fits"
    try:
        prffile = glob.glob(prfglob)[0]
    except:
        message = "ERROR -- KEPPRF: No PRF file found in " + prfdir
        kepmsg.err(logfile, message, True)
        return None

    # read PRF images
    prfn = [0, 0, 0, 0, 0]
    crpix1p = np.zeros((5), dtype="float32")
    crpix2p = np.zeros((5), dtype="float32")
    crval1p = np.zeros((5), dtype="float32")
    crval2p = np.zeros((5), dtype="float32")
    cdelt1p = np.zeros((5), dtype="float32")
    cdelt2p = np.zeros((5), dtype="float32")
    for i in range(5):
        prfn[i], crpix1p[i], crpix2p[i], crval1p[i], crval2p[i], cdelt1p[i], cdelt2p[i], status = kepio.readPRFimage(
            prffile, i + 1, logfile, True
        )
    prfn = np.array(prfn)
    PRFx = np.arange(0.5, np.shape(prfn[0])[1] + 0.5)
    PRFy = np.arange(0.5, np.shape(prfn[0])[0] + 0.5)
    PRFx = (PRFx - np.size(PRFx) / 2) * cdelt1p[0]
    PRFy = (PRFy - np.size(PRFy) / 2) * cdelt2p[0]

    # interpolate the calibrated PRF shape to the target position
    prf = np.zeros(np.shape(prfn[0]), dtype="float32")
    prfWeight = np.zeros((5), dtype="float32")
    for i in range(5):
        prfWeight[i] = np.sqrt((column - crval1p[i]) ** 2 + (row - crval2p[i]) ** 2)
        if prfWeight[i] == 0.0:
            prfWeight[i] = 1.0e-6
        prf = prf + prfn[i] / prfWeight[i]
    prf = prf / np.nansum(prf) / cdelt1p[0] / cdelt2p[0]

    # location of the data image centered on the PRF image (in PRF pixel units)
    prfDimY = int(ydim / cdelt1p[0])
    prfDimX = int(xdim / cdelt2p[0])
    PRFy0 = (np.shape(prf)[0] - prfDimY) / 2
    PRFx0 = (np.shape(prf)[1] - prfDimX) / 2

    # interpolation function over the PRF
    splineInterpolation = scipy.interpolate.RectBivariateSpline(PRFx, PRFy, prf)

    # construct mesh for background model
    if background:
        bx = np.arange(1.0, float(xdim + 1))
        by = np.arange(1.0, float(ydim + 1))
        xx, yy = np.meshgrid(np.linspace(bx.min(), bx.max(), xdim), np.linspace(by.min(), by.max(), ydim))

    # fit PRF model to pixel data
    start = time.time()
    if focus and background:
        args = (DATx, DATy, DATimg, ERRimg, nsrc, border, xx, yy, splineInterpolation, float(x[0]), float(y[0]))
        ans = fmin_powell(kepfunc.PRFwithFocusAndBackground, guess, args=args, xtol=xtol, ftol=ftol, disp=False)
    elif focus and not background:
        args = (DATx, DATy, DATimg, ERRimg, nsrc, splineInterpolation, float(x[0]), float(y[0]))
        ans = fmin_powell(kepfunc.PRFwithFocus, guess, args=args, xtol=xtol, ftol=ftol, disp=False)
    elif background and not focus:
        args = (DATx, DATy, DATimg, ERRimg, nsrc, border, xx, yy, splineInterpolation, float(x[0]), float(y[0]))
        ans = fmin_powell(kepfunc.PRFwithBackground, guess, args=args, xtol=xtol, ftol=ftol, disp=False)
    else:
        args = (DATx, DATy, DATimg, ERRimg, nsrc, splineInterpolation, float(x[0]), float(y[0]))
        ans = fmin_powell(kepfunc.PRF, guess, args=args, xtol=xtol, ftol=ftol, disp=False)
    kepmsg.log(logfile, "Convergence time = %.2fs\n" % (time.time() - start), True)

    # pad the PRF data if the PRF array is smaller than the data array
    flux = []
    OBJx = []
    OBJy = []
    PRFmod = np.zeros((prfDimY, prfDimX))
    if PRFy0 < 0 or PRFx0 < 0.0:
        PRFmod = np.zeros((prfDimY, prfDimX))
        superPRF = np.zeros((prfDimY + 1, prfDimX + 1))
        superPRF[
            np.abs(PRFy0) : np.abs(PRFy0) + np.shape(prf)[0], np.abs(PRFx0) : np.abs(PRFx0) + np.shape(prf)[1]
        ] = prf
        prf = superPRF * 1.0
        PRFy0 = 0
        PRFx0 = 0

    # rotate the PRF model around its center
    if focus:
        angle = ans[-1]
        prf = rotate(prf, -angle, reshape=False, mode="nearest")

    # iterate through the sources in the best fit PSF model
    for i in range(nsrc):
        flux.append(ans[i])
        OBJx.append(ans[nsrc + i])
        OBJy.append(ans[nsrc * 2 + i])

        # calculate best-fit model
        y = (OBJy[i] - np.mean(DATy)) / cdelt1p[0]
        x = (OBJx[i] - np.mean(DATx)) / cdelt2p[0]
        prfTmp = shift(prf, [y, x], order=3, mode="constant")
        prfTmp = prfTmp[PRFy0 : PRFy0 + prfDimY, PRFx0 : PRFx0 + prfDimX]
        PRFmod = PRFmod + prfTmp * flux[i]
        wx = 1.0
        wy = 1.0
        angle = 0
        b = 0.0

        # write out best fit parameters
        txt = "Flux = %10.2f e-/s " % flux[i]
        txt += "X = %9.4f pix " % OBJx[i]
        txt += "Y = %9.4f pix " % OBJy[i]
        kepmsg.log(logfile, txt, True)

    if background:
        bterms = border + 1
        if bterms == 1:
            b = ans[nsrc * 3]
        else:
            bcoeff = np.array([ans[nsrc * 3 : nsrc * 3 + bterms], ans[nsrc * 3 + bterms : nsrc * 3 + bterms * 2]])
            bkg = kepfunc.polyval2d(xx, yy, bcoeff)
            b = nanmean(bkg.reshape(bkg.size))
        txt = "\n   Mean background = %.2f e-/s" % b
        kepmsg.log(logfile, txt, True)
    if focus:
        wx = ans[-3]
        wy = ans[-2]
        angle = ans[-1]
        if not background:
            kepmsg.log(logfile, "", True)
        kepmsg.log(logfile, " X/Y focus factors = %.3f/%.3f" % (wx, wy), True)
        kepmsg.log(logfile, "PRF rotation angle = %.2f deg" % angle, True)

    # measure flux fraction and contamination

    # LUGER: This looks horribly bugged. ``PRFall`` is certainly NOT the sum of the all the sources.
    # Check out my comments in ``kepfunc.py``.

    PRFall = kepfunc.PRF2DET(flux, OBJx, OBJy, DATx, DATy, wx, wy, angle, splineInterpolation)
    PRFone = kepfunc.PRF2DET([flux[0]], [OBJx[0]], [OBJy[0]], DATx, DATy, wx, wy, angle, splineInterpolation)

    # LUGER: Add up contaminant fluxes
    PRFcont = np.zeros_like(PRFone)
    for ncont in range(1, len(flux)):
        PRFcont += kepfunc.PRF2DET(
            [flux[ncont]], [OBJx[ncont]], [OBJy[ncont]], DATx, DATy, wx, wy, angle, splineInterpolation
        )
    PRFcont[np.where(PRFcont < 0)] = 0

    FluxInMaskAll = np.nansum(PRFall)
    FluxInMaskOne = np.nansum(PRFone)
    FluxInAperAll = 0.0
    FluxInAperOne = 0.0
    FluxInAperAllTrue = 0.0

    for i in range(1, ydim):
        for j in range(1, xdim):
            if kepstat.bitInBitmap(maskimg[i, j], 2):
                FluxInAperAll += PRFall[i, j]
                FluxInAperOne += PRFone[i, j]
                FluxInAperAllTrue += PRFone[i, j] + PRFcont[i, j]
    FluxFraction = FluxInAperOne / flux[0]
    try:
        Contamination = (FluxInAperAll - FluxInAperOne) / FluxInAperAll
    except:
        Contamination = 0.0

    # LUGER: Pixel crowding metrics
    Crowding = PRFone / (PRFone + PRFcont)
    Crowding[np.where(Crowding < 0)] = np.nan

    # LUGER: Optimal aperture crowding metric
    CrowdAper = FluxInAperOne / FluxInAperAllTrue

    kepmsg.log(logfile, "\n                Total flux in mask = %.2f e-/s" % FluxInMaskAll, True)
    kepmsg.log(logfile, "               Target flux in mask = %.2f e-/s" % FluxInMaskOne, True)
    kepmsg.log(logfile, "            Total flux in aperture = %.2f e-/s" % FluxInAperAll, True)
    kepmsg.log(logfile, "           Target flux in aperture = %.2f e-/s" % FluxInAperOne, True)
    kepmsg.log(logfile, "  Target flux fraction in aperture = %.2f%%" % (FluxFraction * 100.0), True)
    kepmsg.log(logfile, "Contamination fraction in aperture = %.2f%%" % (Contamination * 100.0), True)
    kepmsg.log(logfile, "       Crowding metric in aperture = %.4f" % (CrowdAper), True)
    kepmsg.log(logfile, "          Crowding metric from TPF = %.4f" % (CrowdTPF), True)

    # constuct model PRF in detector coordinates
    PRFfit = PRFall + 0.0
    if background and bterms == 1:
        PRFfit = PRFall + b
    if background and bterms > 1:
        PRFfit = PRFall + bkg

    # calculate residual of DATA - FIT
    PRFres = DATimg - PRFfit
    FLUXres = np.nansum(PRFres) / npix

    # calculate the sum squared difference between data and model
    Pearson = np.abs(np.nansum(np.square(DATimg - PRFfit) / PRFfit))
    Chi2 = np.nansum(np.square(DATimg - PRFfit) / np.square(ERRimg))
    DegOfFreedom = npix - len(guess) - 1
    try:
        kepmsg.log(logfile, "\n       Residual flux = %.2f e-/s" % FLUXres, True)
        kepmsg.log(logfile, "Pearson's chi^2 test = %d for %d dof" % (Pearson, DegOfFreedom), True)
    except:
        pass
    kepmsg.log(logfile, "          Chi^2 test = %d for %d dof" % (Chi2, DegOfFreedom), True)

    # image scale and intensity limits for plotting images
    imgdat_pl, zminfl, zmaxfl = kepplot.intScale2D(DATimg, imscale)
    imgprf_pl, zminpr, zmaxpr = kepplot.intScale2D(PRFmod, imscale)
    imgfit_pl, zminfi, zmaxfi = kepplot.intScale2D(PRFfit, imscale)
    imgres_pl, zminre, zmaxre = kepplot.intScale2D(PRFres, "linear")
    if imscale == "linear":
        zmaxpr *= 0.9
    elif imscale == "logarithmic":
        zmaxpr = np.max(zmaxpr)
        zminpr = zmaxpr / 2

    # plot
    pl.figure(figsize=[12, 10])
    pl.clf()

    # data
    plotimage(imgdat_pl, zminfl, zmaxfl, 1, row, column, xdim, ydim, 0.07, 0.58, "observation", cmap, lcolor)
    pl.text(
        0.05,
        0.05,
        "CROWDSAP: %.4f" % CrowdTPF,
        horizontalalignment="left",
        verticalalignment="center",
        fontsize=18,
        fontweight=500,
        color=lcolor,
        transform=pl.gca().transAxes,
    )
    kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 1, acolor, "--", 0.5)
    kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 2, acolor, "-", 3.0)

    # model
    plotimage(imgprf_pl, zminpr, zmaxpr, 2, row, column, xdim, ydim, 0.445, 0.58, "model", cmap, lcolor)
    pl.text(
        0.05,
        0.05,
        "Crowding: %.4f" % CrowdAper,
        horizontalalignment="left",
        verticalalignment="center",
        fontsize=18,
        fontweight=500,
        color=lcolor,
        transform=pl.gca().transAxes,
    )
    for x, y in zip(OBJx, OBJy):
        pl.scatter(x, y, marker="x", color="w")
    kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 1, acolor, "--", 0.5)
    kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 2, acolor, "-", 3.0)

    if srcinfo is not None:
        kepid, sx, sy, kepmag = srcinfo
        for i in range(len(sx) - 1, -1, -1):
            if kepid[i] != 0 and kepmag[i] != 0.0:
                size = max(np.array([80.0, 80.0 + (2.5 ** (18.0 - max(12.0, float(kepmag[i])))) * 250.0]))
                pl.scatter(sx[i], sy[i], s=size, facecolors="g", edgecolors="k", alpha=0.1)
            else:
                pl.scatter(sx[i], sy[i], s=80, facecolors="r", edgecolors="k", alpha=0.1)

    # binned model
    plotimage(imgfit_pl, zminfl, zmaxfl, 3, row, column, xdim, ydim, 0.07, 0.18, "fit", cmap, lcolor, crowd=Crowding)
    kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 1, acolor, "--", 0.5)
    kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 2, acolor, "-", 3.0)

    # residuals
    reslim = max(np.abs(zminre), np.abs(zmaxre))
    plotimage(imgres_pl, -reslim, reslim, 4, row, column, xdim, ydim, 0.445, 0.18, "residual", "coolwarm", lcolor)
    kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 1, acolor, "--", 0.5)
    kepplot.borders(maskimg, xdim, ydim, pixcoord1, pixcoord2, 2, acolor, "-", 3.0)

    # plot data color bar
    barwin = pl.axes([0.84, 0.18, 0.03, 0.8])
    if imscale == "linear":
        brange = np.arange(zminfl, zmaxfl, (zmaxfl - zminfl) / 1000)
    elif imscale == "logarithmic":
        brange = np.arange(10.0 ** zminfl, 10.0 ** zmaxfl, (10.0 ** zmaxfl - 10.0 ** zminfl) / 1000)
    elif imscale == "squareroot":
        brange = np.arange(zminfl ** 2, zmaxfl ** 2, (zmaxfl ** 2 - zminfl ** 2) / 1000)
    if imscale == "linear":
        barimg = np.resize(brange, (1000, 1))
    elif imscale == "logarithmic":
        barimg = np.log10(np.resize(brange, (1000, 1)))
    elif imscale == "squareroot":
        barimg = np.sqrt(np.resize(brange, (1000, 1)))
    try:
        nrm = len(str(int(np.nanmax(brange)))) - 1
    except:
        nrm = 0
    brange = brange / 10 ** nrm
    pl.imshow(
        barimg,
        aspect="auto",
        interpolation="nearest",
        origin="lower",
        vmin=np.nanmin(barimg),
        vmax=np.nanmax(barimg),
        extent=(0.0, 1.0, brange[0], brange[-1]),
        cmap=cmap,
    )
    barwin.yaxis.tick_right()
    barwin.yaxis.set_label_position("right")
    barwin.yaxis.set_major_locator(MaxNLocator(7))
    pl.gca().yaxis.set_major_formatter(pl.ScalarFormatter(useOffset=False))
    pl.gca().set_autoscale_on(False)
    pl.setp(pl.gca(), xticklabels=[], xticks=[])
    pl.ylabel("Flux (10$^%d$ e$^-$ s$^{-1}$)" % nrm)
    pl.setp(barwin.get_yticklabels(), "rotation", 90)
    barwin.yaxis.set_major_formatter(FormatStrFormatter("%.1f"))

    # plot residual color bar
    barwin = pl.axes([0.07, 0.08, 0.75, 0.03])
    brange = np.arange(-reslim, reslim, reslim / 500)
    barimg = np.resize(brange, (1, 1000))
    pl.imshow(
        barimg,
        aspect="auto",
        interpolation="nearest",
        origin="lower",
        vmin=np.nanmin(barimg),
        vmax=np.nanmax(barimg),
        extent=(brange[0], brange[-1], 0.0, 1.0),
        cmap="coolwarm",
    )
    barwin.xaxis.set_major_locator(MaxNLocator(7))
    pl.gca().xaxis.set_major_formatter(pl.ScalarFormatter(useOffset=False))
    pl.gca().set_autoscale_on(False)
    pl.setp(pl.gca(), yticklabels=[], yticks=[])
    pl.xlabel("Residuals (e$^-$ s$^{-1}$)")
    barwin.xaxis.set_major_formatter(FormatStrFormatter("%.1f"))

    # render plot
    pl.show(block=True)
    pl.close()

    # stop time
    kepmsg.clock("\nKEPPRF ended at", logfile, True)

    return Crowding