Exemple #1
0
def mkTinyTimPSF( x, y, fltfile, ext=1,
                  fileroot='tinytim', psfdir='tinytim',
                  specfile='flat_flam_tinytim.dat',
                  verbose=False, clobber=False ):
    """ run tinytim to construct a model psf 
    in the distorted (flt) frame
    """
    # TODO : use a redshifted SN spectrum !!!
    #   (will have to build each psf separately)

    # TinyTim generates a psf image centered on 
    # the middle of a pixel
    #  we use "tiny3 SUB=5" for 5x sub-sampling,
    #  then interpolate and shift the sub-sampled psf
    #  to recenter it away from the center of the pixel
    #  Re-bin into normal pixel sampling, and then 
    #  convolve with the charge diffusion kernel from
    #  the fits header. 

    import time
    from numpy import iterable, zeros
    from scipy.ndimage import zoom
    # from util.fitsio import tofits
    import cntrd
    import pyfits

    imhdr0 = pyfits.getheader( fltfile, ext=0 )
    imhdr = pyfits.getheader( fltfile, ext=ext )
    instrument = imhdr0['instrume']
    detector = imhdr0['detector']
    if ( instrument=='WFC3' and detector=='IR' ) : 
        camera='ir'
        filt = imhdr0['filter']
        ccdchip = None
    elif ( instrument=='WFC3' and detector=='UVIS' ) : 
        camera='uvis'
        filt = imhdr0['filter']
        ccdchip = imhdr['CCDCHIP']
    elif ( instrument=='ACS' and detector=='WFC' ) : 
        camera='acs'
        filter1 = imhdr0['filter1']
        filter2 = imhdr0['filter2']
        if filter1.startswith('F') : filt=filter1
        else : filt=filter2
        ccdchip = imhdr['CCDCHIP']

    pixscale = getpixscale( fltfile, ext=('SCI',1) )

    if not os.path.isfile( specfile ) : 
        if 'TINYTIM' in os.environ :
            tinytimdir = os.environ['TINYTIM']
            specfile = os.path.join( tinytimdir, specfile )
    if not os.path.isfile( specfile ) :
        thisfile = sys.argv[0]
        if thisfile.startswith('ipython'): thisfile = __file__
        thisdir = os.path.dirname( thisfile )
        specfile = os.path.join( thisdir, specfile )
    if not os.path.isfile( specfile ) :
        raise exceptions.RuntimeError("Can't find TinyTim spec file %s"%
                                      os.path.basename(specfile) )
    if verbose :
        print( "Using TinyTim spectrum file : %s"%specfile )

    if not iterable(x) : x = [x]
    if not iterable(y) : y = [y]

    if iterable( ext ) :
        extname = ''.join( str(extbit).lower() for extbit in ext )
    else :
        extname = str(ext).lower()
    coordfile = "%s.%s.coord"%(os.path.join(psfdir,fileroot),extname)

    if not os.path.isdir(psfdir) : os.mkdir( psfdir )
    newcoords=True
    if os.path.isfile( coordfile ) and not clobber :
        print( "%s exists. Not clobbering."%coordfile )
        newcoords=False

    psfstamplist = []
    if newcoords: fout = open( coordfile ,'w')
    allexist = True

    i=0
    for xx,yy in zip(x,y):
        # here we give the integer component of the x,y coordinates.
        # after running tiny3, we will shift the psf to account for the 
        # fractional coordinate components
        if newcoords: print >>fout,"%6i %6i"%(int(xx),int(yy))
        if len(x)<=100:
            psfstamp = os.path.join(psfdir,"%s.%s.%02i.fits"%(fileroot,extname,i))
        else : 
            psfstamp = os.path.join(psfdir,"%s.%s.%03i.fits"%(fileroot,extname,i))
        if not os.path.isfile( psfstamp ) : allexist = False
        psfstamplist.append( psfstamp)
        i+=1
    if newcoords: fout.close()

    if allexist and not clobber : 
        print( "All necessary tinytim psf files exist. Not clobbering.")
        return( psfstamplist )

    queryfile = "%s.%s.query"%(os.path.join(psfdir,fileroot),extname)
    fout = open( queryfile ,'w')
    despace = 0.0 # as of tinytim v7.1 : must provide 2ndary mirror despace
    if camera == 'ir' : 
        print >> fout, """23\n @%s\n %s\n 5\n %s\n %.1f\n %.1f\n %s.%s."""%(
            coordfile, filt.lower(), specfile, 
            PSFSIZE, despace, os.path.join(psfdir,fileroot), extname )
    elif camera == 'uvis' : 
        print >> fout,"""22\n %i\n @%s\n %s\n 5\n %s\n %.1f\n %.1f\n %s.%s."""%(
            ccdchip, coordfile, filt.lower(), specfile, 
            PSFSIZE, despace, os.path.join(psfdir,fileroot), extname )
    elif camera == 'acs' : 
        print >> fout,"""15\n %i\n @%s\n %s\n 5\n %s\n %.1f\n %.1f\n %s.%s."""%(
            ccdchip, coordfile, filt.lower(), specfile, 
            PSFSIZE, despace, os.path.join(psfdir,fileroot), extname )
    fout.close()
    
    # run tiny1 to generate the tinytim paramater file
    command1 =  "cat %s | %s %s.%s.in"%(
        queryfile, 'tiny1',
        os.path.join(psfdir,fileroot), extname )
    if verbose : print command1
    os.system( command1 )

    # run tiny2 to generate the distortion-free psfs
    command2 =  "%s %s.%s.in"%(
        'tiny2', os.path.join(psfdir,fileroot), extname )
    if verbose : print command2
    os.system( command2 ) 

    xgeo_offsets = []
    ygeo_offsets = []
    # fluxcorrs = []  # 2014.07.18 Flux correction disabled by Steve
    #run tiny3 and measure the how much offset the geometric distortion adds
    for Npsf in range(len(x)): 
        command3 =  "%s %s.%s.in POS=%i"%(
            'tiny3', os.path.join(psfdir,fileroot), extname, Npsf )
        if verbose : 
            print time.asctime() 
            print command3
        os.system( command3 )
        #Calculate the expected center of the image
        #Get the dimensions of the stamp. 
        if len(x) <= 100 :
            this_stamp = '%s.%s.%02i.fits' %(os.path.join(psfdir,fileroot),extname,Npsf)
        else : 
            this_stamp = '%s.%s.%03i.fits' %(os.path.join(psfdir,fileroot),extname,Npsf)
        xdim = int(pyfits.getval(this_stamp,'NAXIS1'))
        ydim = int(pyfits.getval(this_stamp,'NAXIS2'))

        #The center will be in dimension/2 + 1
        xcen = float(xdim/2 + 1)
        ycen = float(ydim/2 + 1)
        
        #run phot to measure the true center position
        if instrument =='WFC3': instrument = instrument +'_'+detector
        fwhmpix = 0.13 / pixscale  # approximate HST psf size, in pixels
        this_stamp_data = pyfits.getdata( this_stamp )
        meas_xcen, meas_ycen = cntrd.cntrd(this_stamp_data,xcen,ycen,fwhmpix)

        #Subtract the expected center from the measured center
        # note the +1 to account for 0-indexed python convention in cntrd
        # which is different from the 1-indexed fits convention
        #Save the offsets
        xgeo_offsets.append(meas_xcen + 1 - xcen)
        ygeo_offsets.append(meas_ycen + 1 - ycen)
        # fluxcorrs.append(meas_fluxcorr)
        #Move this stamp so that it doesn't get overwritten.
        os.rename(this_stamp,os.path.splitext(this_stamp)[0]+'_tiny3.fits')
        
        
    # run tiny3 to add in geometric distortion and 5x sub-sampling
    for Npsf in range(len(x)): 
        command3 =  "%s %s.%s.in POS=%i SUB=5"%(
            'tiny3', os.path.join(psfdir,fileroot), extname, Npsf )
        if verbose : 
            print time.asctime() 
            print command3
        os.system( command3 ) 

    outstamplist = []
    for xx,yy,psfstamp,xgeo,ygeo in zip( x,y,psfstamplist,xgeo_offsets,ygeo_offsets):
        if verbose : print("sub-sampling psf at %.2f %.2f to 0.01 pix"%(xx,yy))

        # read in tiny3 output psf (sub-sampled to a 5th of a pixel)
        psfim = pyfits.open( psfstamp )
        psfdat = psfim[0].data.copy()
        hdr = psfim[0].header.copy()
        psfim.close()
        #If the number of pixels is even then the psf is centered at pixel n/2 + 1
        # if you are one indexed or n/2 if you are zero indexed. 
        #If the psf image is even, we need to pad the right side with a row (or column) of zeros
        if psfdat.shape[0] % 2 == 0: 
            tmpdat = zeros([psfdat.shape[0]+1,psfdat.shape[1]])
            tmpdat[:-1,:] = psfdat[:,:]
            psfdat = tmpdat
        if psfdat.shape[1] % 2 == 0: 
            tmpdat = zeros([psfdat.shape[0],psfdat.shape[1]+1])
            tmpdat[:,:-1] = psfdat[:,:]
            psfdat = tmpdat
       
        #Now the center of the psf is exactly in the center of the image and the psf image has
        #odd dimensions
        
        #TinyTim returns the psf subsampled at a 5th of a pixel 
        #but not necessarily psfim.shape % 5 == 0. 
        
        #Now we need to pad the array with zeros so that center of the image will be in 
        #the center of both the 1/5th pixel image and the psf at native scale. 
        #As the center of the psf is at the center, all we need to do is add pixels to both
        #sides evenly until we have an integer number of native pixels. 
        # All of the rules assume that the dimensions are odd which makes the rules
        #a little confusing.
         
        xpad,ypad = psfdat.shape[1] % 5, psfdat.shape[0] % 5
        
        if xpad == 2:
            tmpdat = zeros([psfdat.shape[0],psfdat.shape[1]+8])
            tmpdat[:,4:-4] = psfdat[:,:]
            psfdat = tmpdat
        elif xpad == 4:
            tmpdat = zeros([psfdat.shape[0],psfdat.shape[1]+6])
            tmpdat[:,3:-3] = psfdat[:,:]
            psfdat = tmpdat
        elif xpad == 1:
            tmpdat = zeros([psfdat.shape[0],psfdat.shape[1]+4])
            tmpdat[:,2:-2] = psfdat[:,:]
            psfdat = tmpdat
        elif xpad == 3:
            tmpdat = zeros([psfdat.shape[0],psfdat.shape[1]+2])
            tmpdat[:,1:-1] = psfdat[:,:]
            psfdat = tmpdat
            
        if ypad == 2:
            tmpdat = zeros([psfdat.shape[0]+8,psfdat.shape[1]])
            tmpdat[4:-4,:] = psfdat[:,:]
            psfdat = tmpdat
        elif ypad == 4:
            tmpdat = zeros([psfdat.shape[0]+6,psfdat.shape[1]])
            tmpdat[3:-3,:] = psfdat[:,:]
            psfdat = tmpdat
        elif ypad == 1:
            tmpdat = zeros([psfdat.shape[0]+4,psfdat.shape[1]])
            tmpdat[2:-2,:] = psfdat[:,:]
            psfdat = tmpdat
        elif ypad == 3:
            tmpdat = zeros([psfdat.shape[0]+2,psfdat.shape[1]])
            tmpdat[1:-1,:] = psfdat[:,:]
            psfdat = tmpdat

        #Add 2 extra pixels on both sides (+ 400 in each dimension) to account for the fractional shift
        #and the geometric distortion

        psfdat100 = zeros([psfdat.shape[0]*20 + 400, psfdat.shape[1]*20 + 400])
        
        #Calculate the fractional shifts
        xfrac,yfrac = int(round(xx % 1 * 100)), int(round(yy % 1 * 100))
        if yfrac == 100: yfrac = 0
        if xfrac == 100: xfrac = 0
        
        #Add the geometric distorition offsets of the centroid into xfrac and yfrac. 
        #This makes the assumption that the distortion centroid offsets are less than 1 pixel
        #This has been the case for all of my tests.
        if verbose: print('Adding %0.2f, %0.2f to correct the center of the psf for geometric distortion' % (xgeo,ygeo))
        xfrac -= int(100*xgeo)
        yfrac -= int(100*ygeo)
        
        if verbose : print("    Interpolating and re-sampling with sub-pixel shift")

        # interpolate at a 20x smaller grid to get 
        #  sub-sampling at the 100th of a pixel level
        #Right now we use the ndimage zoom function which does a spline interpolation, but is fast
        try : psfdat100[200+yfrac:-(200-yfrac),200+xfrac:-(200-xfrac)] = zoom(psfdat,20)
        except ValueError as e:
            print( e )
            import pdb; pdb.set_trace()
        
        # re-bin on a new grid to get the psf at the full-pixel scale          
        psfdat1 = rebin(psfdat100, 100)
        #remove any reference to psfdat100 in hopes of it getting garbage collected 
        #as it is by far the biggest thing we have in memory
        del psfdat100
        psfdat1 = psfdat1 / psfdat1.sum()
    
        # Blur the re-binned psf to account for detector effects:
        # For  UVIS and ACS, read in the charge diffusion kernel
        # For IR, we use a fixed IR inter-pixel capacitance kernel, defined above
        if verbose : print("    convolving with charged diffusion or inter-pixel capacitance kernel")
        if camera == 'ir': kernel=KERNEL_WFC3IR
        else : kernel = getCDkernel( psfim[0].header ) 

        psfdat2 = convolvepsf( psfdat1, kernel )

        # 2014.07.18 : Disabled by Steve
        # Rescale the TinyTim psf to match the measured aperture corrections.
        # psfdat2 *= fluxcorr
        # if verbose : print('Applying a %f flux correction to the TinyTim psf.' % fluxcorr)

        # write out the new recentered psf stamp
        outstamp = psfstamp.replace('.fits','_final.fits')
        hdr['naxis1']=psfdat2.shape[1]
        hdr['naxis2']=psfdat2.shape[0]
        pyfits.writeto( outstamp, psfdat2, header=hdr, clobber=True )
        if verbose : print("    Shifted, resampled psf written to %s"%outstamp)
        outstamplist.append( outstamp )

    # return a list of  psf stamps 
    return( outstamplist )    
def add_and_recover(imagedat, psfmodel, xy, fluxscale=1, psfradius=5,
                    skyannpix=None, skyalgorithm='sigmaclipping',
                    setskyval=None, recenter=False, ronoise=1, phpadu=1,
                    cleanup=True, verbose=False, debug=False):
    """  Add a single fake star psf model to the image at the given position
    and flux scaling, re-measure the flux at that position and report it,
    Also deletes the planted psf from the imagedat array so that we don't
    pollute that image array.

    :param imagedat: target image numpy data array
    :param psfmodel: psf model fits file or tuple with [gaussparam,lookuptable]
    :param xy: x,y position for fake psf, using the IDL/python convention
        where [0,0] is the lower left corner.
    :param fluxscale: flux scaling to apply to the planted psf
    :param recenter: use cntrd to locate the center of the added psf, instead
        of relying on the input x,y position to define the psf fitting
    :param cleanup: remove the planted psf from the input imagedat array.
    :return:
    """
    if not skyannpix:
        skyannpix = [8, 15]

    # add the psf to the image data array
    imdatwithpsf = addtoimarray(imagedat, psfmodel, xy, fluxscale=fluxscale)

    # TODO: allow for uncertainty in the x,y positions

    gaussparam, lookuptable, psfmag, psfzpt = rdpsfmodel(psfmodel)

    # generate an instance of the pkfit class for this psf model
    # and target image
    pk = pkfit_class(imdatwithpsf, gaussparam, lookuptable, ronoise, phpadu)
    x, y = xy

    if debug:
        from .photfunctions import showpkfit
        from matplotlib import pyplot as pl, cm

        fig = pl.figure(3)
        showpkfit(imdatwithpsf, psfmodel, xy, 11, fluxscale, verbose=True)

        fig = pl.figure(1)
        pl.imshow(imdatwithpsf[y - 20:y + 20, x - 20:x + 20], cmap=cm.Greys,
                  interpolation='nearest')
        pl.colorbar()

        import pdb

        pdb.set_trace()

    if recenter:
        xc, yc = cntrd(imdatwithpsf, x, y, psfradius, verbose=verbose)
        if xc > 0 and yc > 0 and abs(xc - xy[0]) < 5 and abs(yc - xy[1]) < 5:
            x, y = xc, yc
    # do aperture photometry to get the sky
    aperout = aper(imdatwithpsf, x, y, phpadu=phpadu,
                   apr=psfradius * 3, skyrad=skyannpix,
                   setskyval=(setskyval is not None and setskyval),
                   zeropoint=psfzpt, exact=False,
                   verbose=verbose, skyalgorithm=skyalgorithm,
                   debug=debug)
    apmag, apmagerr, apflux, apfluxerr, sky, skyerr, apbadflag, apoutstr\
        = aperout

    # do the psf fitting
    try:
        scale = pk.pkfit_fast_norecenter(1, x, y, sky, psfradius)
        fluxpsf = scale * 10 ** (-0.4 * (psfmag - psfzpt))
    except RuntimeWarning:
        print("photfunctions.add_and_recover failed on RuntimeWarning")
        fluxpsf = -99
    if cleanup:
        # remove the fake psf from the image
        imagedat = addtoimarray(imdatwithpsf, psfmodel, xy,
                                fluxscale=-fluxscale)

    return apflux[0], fluxpsf, [x, y]
def get_flux_and_err(imagedat, psfmodel, xy, ntestpositions=100, psfradpix=3,
                     apradpix=3, skyannpix=None, skyalgorithm='sigmaclipping',
                     setskyval=None, recenter_target=True, recenter_fakes=True,
                     exptime=1, exact=True, ronoise=1, phpadu=1, verbose=False,
                     debug=False):
    """  Measure the flux and flux uncertainty for a source at the given x,y
    position using both aperture and psf-fitting photometry.

    Flux errors are measured by planting fake psfs or empty apertures into the
    sky annulus and recovering a distribution of fluxes with forced photometry.

    :param imagedat: target image numpy data array (with the star still there)
    :param psfmodel: psf model fits file or a 4-tuple with
           [gaussparam,lookuptable,psfmag,psfzpt]
    :param xy: x,y position of the center of the fake planting field
    :param ntestpositions: number of test positions for empty apertures
           and/or fake stars to use for determining the flux error empirically.
    :param psfradpix: radius to use for psf fitting, in pixels
    :param apradpix: radius of photometry aperture, in pixels
    :param skyannpix: inner and outer radius of sky annulus, in pixels
    :param skyalgorithm: algorithm to use for determining the sky value from
           the pixels within the sky annulus: 'sigmaclipping' or 'mmm'
    :param setskyval: if not None, use this value for the sky, ignoring
           the skyannulus
    :param recenter_target: use cntrd to locate the target center near the
           given xy position.
    :param recenter_fakes: recenter on each planted fake when recovering it
    :param exptime: exposure time of the image, for determining poisson noise
    :param ronoise: read-out noise, for determining aperture flux error
           analytically
    :param phpadu: photons-per-ADU, for determining aper flux err analytically
    :param verbose: turn verbosity on
    :param debug: enter pdb debugging mode
    :return: apflux, apfluxerr, psfflux, psffluxerr
             The flux measured through the given aperture and through
             psf fitting, along with associated errors.
    """
    if not np.any(skyannpix):
        skyannpix = [8, 15]

    # locate the target star center position
    x, y = xy
    if recenter_target:
        x, y = cntrd(imagedat, x, y, psfradpix)
        if x < 0 or y < 0:
            print("WARNING [photfunctions.py] : recentering failed")
            import pdb
            pdb.set_trace()

    # do aperture photometry directly on the source
    # (Note : using an arbitrary zeropoint of 25 here)
    aperout = aper(imagedat, x, y, phpadu=phpadu,
                   apr=apradpix, skyrad=skyannpix,
                   setskyval=setskyval,
                   zeropoint=25, exact=exact,
                   verbose=verbose, skyalgorithm=skyalgorithm,
                   debug=debug)
    apmag, apmagerr, apflux, apfluxerr, sky, skyerr, apbadflag, apoutstr = \
        aperout

    # define a set of test position points that uniformly samples the sky
    # annulus region, for planting empty apertures and/or fake stars
    rmin = float(skyannpix[0])
    rmax = float(skyannpix[1])
    u = np.random.uniform(rmin, rmax, ntestpositions)
    v = np.random.uniform(0, rmin + rmax, ntestpositions)
    r = np.where(v < u, u, rmax + rmin - u)
    theta = np.random.uniform(0, 2 * np.pi, ntestpositions)
    xtestpositions = r * np.cos(theta) + x
    ytestpositions = r * np.sin(theta) + y

    psfflux = psffluxerr = np.nan
    if psfmodel is not None:
        # set up the psf model realization
        gaussparam, lookuptable, psfmag, psfzpt = rdpsfmodel(psfmodel)
        psfmodel = [gaussparam, lookuptable, psfmag, psfzpt]
        pk = pkfit_class(imagedat, gaussparam, lookuptable, ronoise, phpadu)

        # do the psf fitting
        try:
            scale = pk.pkfit_fast_norecenter(1, x, y, sky, psfradpix)
            psfflux = scale * 10 ** (0.4 * (25. - psfmag))
        except RuntimeWarning:
            print("PythonPhot.pkfit_norecenter failed.")
            psfflux = np.nan

        if np.isfinite(psfflux):
            # remove the target star from the image
            imagedat = addtoimarray(imagedat, psfmodel, [x, y],
                                    fluxscale=-psfflux)

            # plant fakes and recover their fluxes with psf fitting
            # imdatsubarray = imagedat[y-rmax-2*psfradpix:y+rmax+2*psfradpix,
            #                x-rmax-2*psfradpix:x+rmax+2*psfradpix]
            fakecoordlist, fakefluxlist = [], []
            for xt, yt in zip(xtestpositions, ytestpositions):
                    # To ensure appropriate sampling of sub-pixel positions,
                    # we assign random sub-pixel offsets to each position.
                    xt = int(xt) + np.random.random()
                    yt = int(yt) + np.random.random()
                    fakefluxaper, fakefluxpsf, fakecoord = add_and_recover(
                        imagedat, psfmodel, [xt, yt], fluxscale=psfflux,
                        cleanup=True, psfradius=psfradpix, recenter=recenter_fakes)
                    if np.isfinite(fakefluxpsf):
                        fakecoordlist.append(fakecoord)
                        fakefluxlist.append(fakefluxpsf)
            fakefluxlist = np.array(fakefluxlist)
            fakefluxmean, fakefluxsigma = gaussian_fit_to_histogram(fakefluxlist)
            if abs(fakefluxmean - psfflux) > fakefluxsigma and verbose:
                print("WARNING: psf flux may be biased. Fake psf flux tests "
                      "found a significantly non-zero sky value not accounted for "
                      "in measurement of the target flux:  \\"
                      "Mean psf flux offset in sky annulus = %.3e\\" %
                      (fakefluxmean - psfflux) +
                      "sigma of fake flux distribution = %.3e" %
                      fakefluxsigma +
                      "NOTE: this is included as a systematic error, added in "
                      "quadrature to the psf flux err derived from fake psf "
                      "recovery.")
            psfflux_poissonerr = (poissonErr(psfflux * exptime, confidence=1) /
                                  exptime)
            # Total flux error is the quadratic sum of the poisson noise with
            # the systematic (shift) and statistical (dispersion) errors
            # inferred from fake psf planting and recovery
            psffluxerr = np.sqrt(psfflux_poissonerr**2 +
                                 (fakefluxmean - psfflux)**2 +
                                 fakefluxsigma**2)

    # drop down empty apertures and recover their fluxes with aperture phot
    # NOTE : if the star was removed for psf fitting, then we take advantage
    # of that to get aperture flux errors with the star gone.
    emptyaperout = aper(imagedat, np.array(xtestpositions),
                        np.array(ytestpositions), phpadu=phpadu,
                        apr=apradpix, setskyval=sky, zeropoint=25,
                        exact=False, verbose=verbose,
                        skyalgorithm=skyalgorithm, debug=debug)
    emptyapflux = emptyaperout[2]
    if np.any(np.isfinite(emptyapflux)):
        emptyapmeanflux, emptyapsigma = gaussian_fit_to_histogram(emptyapflux)
        emptyapbias = abs(emptyapmeanflux) - emptyapsigma
        if np.any(emptyapbias > 0) and verbose:
            print("WARNING: aperture flux may be biased. Empty aperture flux tests"
                  " found a significantly non-zero sky value not accounted for in "
                  "measurement of the target flux:  \\"
                  "Mean empty aperture flux in sky annulus = %s\\"
                  % emptyapmeanflux +
                  "sigma of empty aperture flux distribution = %s"
                  % emptyapsigma)
        if np.iterable(apflux):
            apflux_poissonerr = np.array(
                [poissonErr(fap * exptime, confidence=1) / exptime
                 for fap in apflux])
        else:
            apflux_poissonerr = (poissonErr(apflux * exptime, confidence=1) /
                                 exptime)
        apfluxerr = np.sqrt(apflux_poissonerr**2 +
                            emptyapbias**2 + emptyapsigma**2)

    else:
        if np.iterable(apradpix):
            apfluxerr = [np.nan for aprad in apradpix]
        else:
            apfluxerr = np.nan

    if psfmodel is not None and np.isfinite(psfflux):
        # return the target star back into the image
        imagedat = addtoimarray(imagedat, psfmodel, [x, y],
                                fluxscale=psfflux)

    if debug > 1:
        import pdb
        pdb.set_trace()

    return apflux, apfluxerr, psfflux, psffluxerr, sky, skyerr
Exemple #4
0
# FWHM for centroiding
def FWHM(X,Y):
	half_max = max(Y) / 2
	d = sign(half_max - array(Y[0:-1])) - sign(half_max - array(Y[1:]))
	left_idx = find(d > 0)[0]
	right_idx = find(d < 0)[-1]
	return X[right_idx] - X[left_idx]

FWHM1 = FWHM(cntrdx1,cntrdy1)
FWHM2 = FWHM(cntrdx2,cntrdy2)
FWHM3 = FWHM(cntrdx3,cntrdy3)
FWHM4 = FWHM(cntrdx4,cntrdy4)
FWHM5 = FWHM(cntrdx5,cntrdy5)

# Putting it together...
ShiftLoc1 = cntrd.cntrd(Corr1,cntrdx1,cntrdy1,FWHM1)
ShiftLoc2 = cntrd.cntrd(Corr2,cntrdx2,cntrdy2,FWHM2)
ShiftLoc3 = cntrd.cntrd(Corr3,cntrdx3,cntrdy3,FWHM3)
ShiftLoc4 = cntrd.cntrd(Corr4,cntrdx4,cntrdy4,FWHM4)
ShiftLoc5 = cntrd.cntrd(Corr5,cntrdx5,cntrdy5,FWHM5)

# Drizzling
NewShiftLoc1 = mskpy.image.imshift(ShiftLoc1,cntrdx1,cntrdy1)
NewShiftLoc2 = mskpy.image.imshift(ShiftLoc2,cntrdx2,cntrdy2)
NewShiftLoc3 = mskpy.image.imshift(ShiftLoc3,cntrdx3,cntrdy3)
NewShiftLoc4 = mskpy.image.imshift(ShiftLoc4,cntrdx4,cntrdy4)
NewShiftLoc5 = mskpy.image.imshift(ShiftLoc5,cntrdx5,cntrdy5)

# Total results
ShiftTot = ShiftLoc1 + ShiftLoc2 + ShiftLoc3 + ShiftLoc4 + ShiftLoc5
medianShiftTot = np.median(ShiftTot)