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
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