Esempio n. 1
0
    def cog(self, window_size, method, tolerance=0.01):
        """
        Curve of growth to determine nominal aperture for photometry using 
        astropy photutils.
        
        Parameters
        ----------
        tolerance : float
            Magnitude difference tolerance between different apertures
        
        Returns
        -------
        aperture : float
            Nominal aperture radius for photmetry
        """
        # Aperture values in pixels
        apertures = np.linspace(2, 25, 24)
        naper = apertures.shape[0]

        # Read input image and star position
        image = csusb.fitsread(self.sci_file)
        pos = np.loadtxt(self.coords, ndmin=2)
        nstars = pos.shape[0]

        # Iterate through the frames and determine nominal aperture
        mags_arr = np.zeros(len(apertures))
        objpos = csusb.recenter(image, pos, window_size, method)
        for i in range(naper):
            flux = self.phot(image, objpos[0, :], aper=apertures[i])
            mags_arr[i] = -2.5 * np.log10(flux["flux"])
        mags_diff = np.diff(mags_arr)
        idx = np.where(np.abs(mags_diff) < 0.01)
        if len(idx[0]) != 0:
            nom_aper = apertures[idx[0][0]]
        else:
            nom_aper = 16.0

        return nom_aper
Esempio n. 2
0
def process(infile, coords, method, inner_radius, outer_radius, cen_method, window_size, threshold, output):
    """
    Entry point function to process science image.
    
    Parameters
    ----------
    infile : string
        Science image or list of science images
        
    coords : string
        Input text file with coordinates of stars
        
    method : string
        FWHM of the stelar psf in pixels
        
    inner_radius : float
        Sky background sigma
        
    outer_radius : int
        Inner sky annulus radius in pixels
        
                
    Returns
    -------
    None 
    """
    print "FASTPHOT: CHIMERA Fast Aperture Photometry Routine"
    
    inner_radius = float(inner_radius)
    outer_radius = float(outer_radius)
    
    # Check if input is a string of FITS images or a text file with file names
    if infile[0] == "@":
        infile = infile[1:]
        
        if not os.path.exists(infile):
            print "REGISTER: Not able to locate file %s" %infile
        
        images = []
        with open(infile, "r") as fd:
            for line in fd.readlines():
                if len(line) > 1:
                    images.append(line.replace("\n", ""))
    else:
        images = infile.split(",")

    # Number of images
    nimgs = len(images)
	
    # Read star coordinate
    pos = np.loadtxt(coords, ndmin = 2)
    nstars = pos.shape[0]

    dtype = [("DATETIME", "S25"),("XCEN", "f4"),("YCEN", "f4"),("MSKY", "f8"),("NSKY", "f8"),("AREA", "f8"),("FLUX_ADU", "f8"),("FLUX_ELEC", "f8"),("FERR", "f8"),("MAG", "f8")]
    phot_data = np.zeros([nimgs, nstars], dtype = dtype)
    for i in range(nimgs):
        sci_file = images[i]
        print "  Processing science image %s" %sci_file

        # Read FITS image
        image = csusb.fitsread(sci_file)
        
        # Instantiate an Aperphot object
        ap = csusb.Aperphot(sci_file, coords)
        
        # Set sigma, annulus and dannulus
        ap.method = method
        ap.inner_radius = inner_radius
        ap.outer_radius = outer_radius
        
        # Determine nominal aperture radius for photometry
        if i == 0:
            nom_aper = ap.cog(window_size, cen_method)
            print "  Nominal aperture radius : %4.1f pixels" %nom_aper
           
        # Perform aperture photometry on all the frames
        objpos = csusb.recenter(image, pos, window_size, cen_method, threshold)
        aperphot_data = ap.phot(image, objpos, nom_aper)
        pos = np.copy(objpos)
            
        phot_data[i,:]['DATETIME'] = ap.utcstart
        phot_data[i,:]['XCEN'] = aperphot_data["xcenter_raw"]
        phot_data[i,:]['YCEN'] = aperphot_data["ycenter_raw"]
        phot_data[i,:]['MSKY'] = aperphot_data["msky"]
        phot_data[i,:]['NSKY'] = aperphot_data["nsky"]
        phot_data[i,:]['AREA'] = aperphot_data["area"]
        phot_data[i,:]['FLUX_ADU'] = aperphot_data["flux"]
        phot_data[i,:]['FLUX_ELEC'] = phot_data[i,:]['FLUX_ADU'] * ap.epadu
        phot_data[i,:]['MAG'] = ap.zmag - 2.5 * np.log10(phot_data[i,:]['FLUX_ELEC']/ap.exptime)
            
        # Calculate error in flux - using the formula
        # err = sqrt(flux * gain + npix * (1 + (npix/nsky)) * (flux_sky * gain + R**2))
        phot_data[i,:]['FERR'] = np.sqrt(phot_data[i]['FLUX_ELEC'] + phot_data[i]['AREA'] * (1 + phot_data[i]['AREA']/phot_data[i]['NSKY']) * (phot_data[i]['MSKY'] * ap.epadu + ap.readnoise**2))
                        
    # Save photometry data in numpy binary format
    print "  Saving photometry data as numpy binary"
    if output != "":
        npy_outfile = output + ".npy"
    else:
        npy_outfile = sci_file.replace(".fits", ".phot.npy")
    if os.path.exists(npy_outfile):
        os.remove(npy_outfile)
            
    np.save(npy_outfile, phot_data)

    # Plot first pass light curve
    if plot_flag:
        print "  Plotting normalized light curve"
        if output != "":
            plt_outfile = output + ".png"
        else:
            plt_outfile = sci_file.replace(".fits", ".lc.png")
        ts = np.zeros(nimgs, dtype = np.int32)
        for i in range(nimgs):
            ts[i] = timedelta(phot_data[0,0]['DATETIME'], phot_data[i,0]['DATETIME'])    
        plotter(phot_data, ts, plt_outfile)
        
    return