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.array([2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]) naper = apertures.shape[0] # Randomly perform curve of growth on 5 frames framenum = np.random.randint(1, self.nframes, 5) apertures = np.linspace(2,20,19) # Read input image and star position image = chimera.fitsread(self.sci_file) pos = np.loadtxt(self.coords, ndmin = 2) # Iterate through the frames and determine nominal aperture nom_aper = np.zeros(5, dtype = np.float32) cnt = 0 for val in framenum: mags_arr = np.zeros(len(apertures)) objpos = chimera.recenter(image[val,:,:], pos, window_size, method) for i in range(naper): flux = self.phot(image[val,:,:], objpos, aper = apertures[i]) try: mags_arr[i] = -2.5 * np.log10(flux['flux']) except: mags_arr[i] = -2.5 * np.log10(flux['flux'][1]) mags_diff = np.diff(mags_arr) idx = np.where((np.abs(mags_diff) < 0.01) & (np.abs(mags_diff) != 0.0)) if len(idx[0]) != 0: nom_aper[cnt] = apertures[idx[0][0]] else: nom_aper[cnt] = 10.0 cnt += 1 return np.median(nom_aper)
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.array([2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]) naper = apertures.shape[0] # Randomly peform curve of growth on 5 frames framenum = np.random.randint(1, self.nframes, 5) apertures = np.linspace(2,20,19) # Read input image and star position image = chimera.fitsread(self.sci_file) pos = np.loadtxt(self.coords, ndmin = 2) # Iterate through the frames and determine nominal aperture nom_aper = np.zeros(5, dtype = np.float32) cnt = 0 for val in framenum: mags_arr = np.zeros(len(apertures)) objpos = chimera.recenter(image[val,:,:], pos, window_size, method) for i in range(naper): flux = self.phot(image[val,:,:], objpos, 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[cnt] = apertures[idx[0][0]] else: nom_aper[cnt] = 12.0 cnt += 1 return np.median(nom_aper)
def animate(image, nframes, vmin, vmax, scale, cmap, fps, outtype): """ Generate animation from CHIMERA image cube. Parameters ---------- image : string CHIMERA FITS image name nframes : int Number of frames to include in animation vmin, vmax : float Minimum and maximum pixel value scale : string Scale the images? (linear or log) cmap : string Matlab colormap fps : int Frames per second for mp4 animation outtype : string Save animation as gif or mp4 Returns ------- anim_fname : string Name of the animation file name. """ print "ANIMATE: Animate CHIMERA 3D image cubes" nframes = int(nframes) vmin = int(vmin) vmax = int(vmax) fps = int(fps) # Create a matplotlib figure fig = plt.figure(figsize=(12, 10)) plt.axis("off") # Read FITS image img_data = chimera.fitsread(image) # Display each frame to create an animation if nframes > img_data.shape[0]: nframes = img_data.shape[0] print " Generating animation" ims = [] for i in range(0, nframes): if scale == 'linear': im = plt.imshow(img_data[i, :, :], origin="lower", cmap=plt.get_cmap(cmap), vmin=vmin, vmax=vmax) else: img_log = np.log10(img_data[i, :, :]) im = plt.imshow(img_log, origin="lower", cmap=plt.get_cmap(cmap), vmin=np.min(img_log), vmax=np.max(img_log)) ims.append([im]) # Animate the frames ani = animation.ArtistAnimation(fig, ims, interval=50, blit=True, repeat_delay=10) # Save the animation if outtype == "gif": anim_fname = image.replace(".fits", ".gif") ani.save(anim_fname, dpi=100, writer="imagemagick") else: anim_fname = image.replace(".fits", ".mp4") ani.save(anim_fname, fps=fps, dpi=100, extra_args=['-vcodec', 'libx264']) return anim_fname
def process(infile, coords, method, inner_radius, outer_radius, cen_method, window_size, output, zmag, avg): """ 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 cen_method : string Centroid method window_size : int Centroid finding window size in pixels output : string Output file name zmag : float Photometric zero point 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) image_cubes = [] with open(infile, "r") as fd: for line in fd.readlines(): if len(line) > 1: image_cubes.append(line.replace("\n", "")) else: image_cubes = infile.split(",") # Number of images ncubes = len(image_cubes) pos = np.loadtxt(coords, ndmin=2) nstars = len(pos) total_phot_data = [] for i in range(ncubes): sci_file = image_cubes[i] print(" Processing science image %s" % sci_file) # Read FITS image and star coordinate image = chimera.fitsread(sci_file) if avg != "": image = time_average(image, avg) avg = int(avg) else: avg = 1 # Instantiate an Aperphot object ap = chimera.Aperphot(sci_file, coords) # Set fwhmpsf, sigma, annulus, dannulus and zmag ap.method = method ap.inner_radius = inner_radius ap.outer_radius = outer_radius if zmag != "": ap.zmag = float(zmag) # Determine nominal aperture radius for photometry if i == 0: nom_aper = ap.cog(window_size, cen_method) #nom_aper = 3 print(" Nominal aperture radius : %4.1f pixels" % nom_aper) # Perform aperture photometry on all the frames 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([nstars, ap.nframes / avg], dtype=dtype) for j in range(ap.nframes / avg): print(" Processing frame number : %d" % (j + 1)) objpos = chimera.recenter(image[j, :, :], pos, window_size, cen_method) aperphot_data = ap.phot(image[j, :, :], objpos, nom_aper) pos = np.copy(objpos) phot_data[:, j]['DATETIME'] = ap.addtime(j * avg * ap.kintime).isoformat() phot_data[:, j]['XCEN'] = aperphot_data["xcenter_raw"] phot_data[:, j]['YCEN'] = aperphot_data["ycenter_raw"] phot_data[:, j]['MSKY'] = aperphot_data["msky"] phot_data[:, j]['NSKY'] = aperphot_data["nsky"] phot_data[:, j]['AREA'] = aperphot_data["area"] phot_data[:, j]['FLUX_ADU'] = aperphot_data["flux"] phot_data[:, j]['FLUX_ELEC'] = phot_data[:, j]['FLUX_ADU'] * ap.epadu phot_data[:, j]['MAG'] = ap.zmag - 2.5 * np.log10( phot_data[:, j]['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[:, j]['FERR'] = np.sqrt( phot_data[:, j]['FLUX_ELEC'] + phot_data[:, j]['AREA'] * (1 + phot_data[:, j]['AREA'] / phot_data[:, j]['NSKY']) * (phot_data[:, j]['MSKY'] * ap.epadu + ap.readnoise**2)) total_phot_data.append(phot_data) # 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") plotter(phot_data, ap.nframes, ap.kintime, plt_outfile) ''' # Convert the total_phot_data to array and reshape it print(' Saving consolidated photometry data...') total_phot_data_arr = np.concatenate(total_phot_data, axis=1) # Save the array as npy file if output != "": np.save(output + "phot_total.npy", total_phot_data_arr) else: np.save("phot_total.npy", total_phot_data_arr) return
def process(sci_files, sci_bias_file, flat_file, nskip, threshold, flat_bias_file, output): """ Entry point function to process science images. Parameters ---------- sci_files : string Science image file names sci_bias_file : string Bias image file name for science images flat_file : string Flat field file name skip : int Number of bias frames to skip before averaging the frames. Default is 0. threshold : float Threshold for normalized fat field (value between 0 and 1.0). Default is 0.8. flat_bias_file : string Bias image file name for flat field images Returns ------- None """ print "REDUCE: CHIMERA Image Reduction Rotuine" nskip = int(nskip) threshold = float(threshold) # Check if input is a string of FITS images or a text file with file names if sci_files[0] == "@": infile = sci_files[1:] if not os.path.exists(infile): print " Not able to locate file %s" % infile image_cubes = [] with open(infile, "r") as fd: for line in fd.readlines(): if len(line) > 1: image_cubes.append(line.replace("\n", "")) else: image_cubes = sci_files.split(",") # Read bias and flat field images sci_bias_image = chimera.fitsread(sci_bias_file) flat_image = chimera.fitsread(flat_file) if flat_bias_file != "": flat_bias_image = chimera.fitsread(flat_bias_file) else: flat_bias_image = sci_bias_image # Create master bias image print " Generating master bias image" master_sci_bias_image = chimera.masterbias(sci_bias_image) master_flat_bias_image = chimera.masterbias(flat_bias_image) # Create normalized flat field print " Generating normalized flat field image" master_flat_image = chimera.masterflat(flat_image, master_flat_bias_image) ncubes = len(image_cubes) for i in range(ncubes): sci_file = image_cubes[i] print " Reducing science image : ", sci_file sci_image, header = chimera.fitsread(sci_file, header=True) # Reduced the science frames sci_red_image, sci_avg_image = chimera.imreduce(sci_image, master_sci_bias_image, master_flat_image) # Write the reduced and average FITS image if output != "": red_file = output + "_final.fits" avg_file = output + "_avg.fits" else: red_file = sci_file.replace(".fits", "_final.fits") avg_file = sci_file.replace(".fits", "_avg.fits") if os.path.exists(red_file): os.remove(red_file) if os.path.exists(avg_file): os.remove(avg_file) chimera.fitswrite(sci_red_image, red_file, header=header) chimera.fitswrite(sci_avg_image, avg_file, header=header) print " Reduced science image : ", red_file return
def process(sci_files, sci_bias_file, flat_file, nskip, threshold, flat_bias_file, output): """ Entry point function to process science images. Parameters ---------- sci_files : string Science image file names sci_bias_file : string Bias image file name for science images flat_file : string Flat field file name skip : int Number of bias frames to skip before averaging the frames. Default is 0. threshold : float Threshold for normalized fat field (value between 0 and 1.0). Default is 0.8. flat_bias_file : string Bias image file name for flat field images Returns ------- None """ print "REDUCE: CHIMERA Image Reduction Rotuine" nskip = int(nskip) threshold = float(threshold) # Check if input is a string of FITS images or a text file with file names if sci_files[0] == "@": infile = sci_files[1:] if not os.path.exists(infile): print " Not able to locate file %s" % infile image_cubes = [] with open(infile, "r") as fd: for line in fd.readlines(): if len(line) > 1: image_cubes.append(line.replace("\n", "")) else: image_cubes = sci_files.split(",") # Read bias and flat field images sci_bias_image = chimera.fitsread(sci_bias_file) flat_image = chimera.fitsread(flat_file) if flat_bias_file != "": flat_bias_image = chimera.fitsread(flat_bias_file) else: flat_bias_image = sci_bias_image # Create master bias image print " Generating master bias image" master_sci_bias_image = chimera.masterbias(sci_bias_image) master_flat_bias_image = chimera.masterbias(flat_bias_image) # Create normalized flat field print " Generating normalized flat field image" master_flat_image = chimera.masterflat(flat_image, master_flat_bias_image) ncubes = len(image_cubes) for i in range(ncubes): sci_file = image_cubes[i] print " Reducing science image : ", sci_file sci_image, header = chimera.fitsread(sci_file, header=True) # Reduced the science frames sci_red_image, sci_avg_image = chimera.imreduce( sci_image, master_sci_bias_image, master_flat_image) # Write the reduced and average FITS image if output != "": red_file = output + "_final.fits" avg_file = output + "_avg.fits" else: red_file = sci_file.replace('.fits', '_final.fits') avg_file = sci_file.replace('.fits', '_avg.fits') if os.path.exists(red_file): os.remove(red_file) if os.path.exists(avg_file): os.remove(avg_file) chimera.fitswrite(sci_red_image, red_file, header=header) chimera.fitswrite(sci_avg_image, avg_file, header=header) print " Reduced science image : ", red_file return
def process(infile, coords, fwhmpsf, sigma, aperture, annulus, dannulus, output, zmag, debug): """ 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 fwhmpsf : float FWHM of the stelar psf in pixels sigma : float Sky background sigma annulus : int Inner sky annulus radius in pixels dannulus : int Radius of sky annulus in pixels output : string Output file name zmag : string Photometric zero point Returns ------- None """ print("PHOTOMETRY: CHIMERA Aperture Photometry Routine") fwhmpsf = float(fwhmpsf) sigma = float(sigma) annulus = int(annulus) dannulus = int(dannulus) # 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): raise IOError("PHOTOMETRY: Not able to locate file %s. Stopping." % infile) image_cubes = [] with open(infile, "r") as fd: for line in fd.readlines(): if len(line) > 1: image_cubes.append(line.replace("\n", "")) else: image_cubes = infile.split(",") # Number of images ncubes = len(image_cubes) # Check if the input coordinates file exists. Take a tmp copy of the input # file and use that. Delete at the end of processing. if not os.path.exists(coords): raise IOError("Input coordinate file %s does not exist. Stopping." % coords) else: tmp_coords = coords + ".tmp" iraf.copy(coords, tmp_coords) # Fields to extract from phot file fields = "XCEN,YCEN,CIER,MSKY,STDEV,NSKY,SIER,SUM,AREA,FLUX,MERR,PIER" total_phot_data = [] img_sec = [] for i in range(ncubes): sci_file = image_cubes[i] if not os.path.exists(sci_file): raise IOError("FITS image %s does not exist. Stopping." % sci_file) fpath, fname = os.path.split(sci_file) print("\n Processing science image %s" % fname) # Instantiate an Aperphot object ap = chimera.Aperphot(sci_file, coords) # Set fwhmpsf, sigma, annulus. dannulus and zero point ap.fwhmpsf = fwhmpsf ap.sigma = sigma ap.annulus = annulus ap.dannulus = dannulus if zmag != "": ap.zmag = float(zmag) # Read the input FITS image if i == 0: img, imghdr = chimera.fitsread(ap.sci_file, header=True) else: img = chimera.fitsread(ap.sci_file) # Determine nominal aperture radius for photometry if i == 0: if aperture: nom_aper = float(aperture) else: nom_aper = ap.daocog() print(" Nominal aperture radius : %4.1f pixels" % nom_aper) # Perform aperture photometry on all the frames dtype = [ ("DATETIME", "S25"), ("XCEN", "f4"), ("YCEN", "f4"), ("CIER", "i4"), ("MSKY", "f4"), ("STDEV", "f4"), ("NSKY", "i4"), ("SIER", "i4"), ("SUM", "f4"), ("AREA", "f4"), ("FLUX_ADU", "f4"), ("FLUX_ELEC", "f4"), ("FERR", "f4"), ("MAG", "f4"), ("MERR", "f4"), ("PIER", "i4"), ] phot_data = np.zeros([ap.nframes], dtype=dtype) for j in range(ap.nframes): print(" Processing frame number : %d" % (j + 1)) outfile = sci_file.replace(".fits", "_" + str(j) + ".phot.1") ap.daophot(j + 1, tmp_coords, outfile, nom_aper) objcen = dump(outfile, "XCEN,YCEN") with open(tmp_coords, "w") as fd: fd.write(objcen + '\n') aperphot_data = dump(outfile, fields).split() phot_data[j]['DATETIME'] = ap.addtime(j * ap.kintime).isoformat() phot_data[j]['XCEN'] = float(aperphot_data[0]) phot_data[j]['YCEN'] = float(aperphot_data[1]) phot_data[j]['CIER'] = int(aperphot_data[2]) phot_data[j]['MSKY'] = float(aperphot_data[3]) phot_data[j]['STDEV'] = float(aperphot_data[4]) phot_data[j]['NSKY'] = int(aperphot_data[5]) phot_data[j]['SIER'] = int(aperphot_data[6]) phot_data[j]['SUM'] = float(aperphot_data[7]) phot_data[j]['AREA'] = float(aperphot_data[8]) phot_data[j]['FLUX_ADU'] = float(aperphot_data[9]) phot_data[j]['FLUX_ELEC'] = float(aperphot_data[9]) * ap.epadu phot_data[j]['MAG'] = ap.zmag - 2.5 * np.log10( phot_data[j]['FLUX_ELEC'] / ap.exptime) if aperphot_data[10] == 'INDEF': phot_data[j]['MERR'] = -10 else: phot_data[j]['MERR'] = float(aperphot_data[10]) phot_data[j]['PIER'] = int(aperphot_data[11]) # Calculate error in flux - using the formula # err = sqrt(flux * gain + npix * (1 + (npix/nsky)) * (flux_sky * gain + R**2)) phot_data[j]['FERR'] = np.sqrt( phot_data[j]['FLUX_ELEC'] + phot_data[j]['AREA'] * (1 + phot_data[j]['AREA'] / phot_data[j]['NSKY']) * (phot_data[j]['MSKY'] * ap.epadu + ap.readnoise**2)) # Save a 51x51 image section of the object xmin, xmax = int(phot_data[j]['XCEN']) - 25, int( phot_data[j]['XCEN']) + 25 ymin, ymax = int(phot_data[j]['YCEN']) - 25, int( phot_data[j]['YCEN']) + 25 img_sec.append(img[j, ymin:ymax, xmin:xmax]) # Save photometry of all the image cubes in a single file total_phot_data.append(phot_data) # If debug mode - # 1. save DAOPHOT phot files # 2. save individual phot data as npy file # 3. Plot light cuve for each data cube separatly if debug: # Save photometry data in numpy binary format print(" Saving photometry data as numpy binary") if output != "": npy_outfile = output + ".npy" else: npy_outfile = coords + "_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 = coords + "_lc.png" plotter(phot_data, ap.nframes, ap.kintime, plt_outfile) else: # Delete intermediate files is not debug mode iraf.delete(os.path.join(fpath, '*.phot.1')) # Convert the total_phot_data to array and reshape it print(' Saving consolidated photometry data...') total_phot_data_arr = np.concatenate(total_phot_data) # Save the array as npy file np.save(coords + "_total.phot.npy", total_phot_data_arr) # Save the image section with object as FITS file print(' Saving image section with object as FITS image...') img_sec_arr = np.asarray(img_sec) img_fname = coords + "_obj.fits" if os.path.exists(img_fname): os.remove(img_fname) chimera.fitswrite(img_sec_arr, coords + "_obj.fits", header=imghdr) # Delete temporary coordinate file if os.path.exists(tmp_coords): os.remove(tmp_coords) return
def animate(image, nframes, vmin, vmax, scale, cmap, fps, outtype): """ Generate animation from CHIMERA image cube. Parameters ---------- image : string CHIMERA FITS image name nframes : int Number of frames to include in animation vmin, vmax : float Minimum and maximum pixel value scale : string Scale the images? (linear or log) cmap : string Matlab colormap fps : int Frames per second for mp4 animation outtype : string Save animation as gif or mp4 Returns ------- anim_fname : string Name of the animation file name. """ print "ANIMATE: Animate CHIMERA 3D image cubes" nframes = int(nframes) vmin = int(vmin) vmax = int(vmax) fps = int(fps) # Create a matplotlib figure fig = plt.figure(figsize = (12,10)) plt.axis("off") # Read FITS image img_data = chimera.fitsread(image) # Display each frame to create an animation if nframes > img_data.shape[0]: nframes = img_data.shape[0] print " Generating animation" ims = [] for i in range(0, nframes): if scale == 'linear': im = plt.imshow(img_data[i,:,:], origin = "lower", cmap = plt.get_cmap(cmap), vmin = vmin, vmax = vmax) else: img_log = np.log10(img_data[i,:,:]) im = plt.imshow(img_log, origin = "lower", cmap = plt.get_cmap(cmap), vmin = np.min(img_log), vmax = np.max(img_log)) ims.append([im]) # Animate the frames ani = animation.ArtistAnimation(fig, ims, interval = 50, blit = True, repeat_delay = 10) # Save the animation if outtype == "gif": anim_fname = image.replace(".fits", ".gif") ani.save(anim_fname, dpi = 100, writer = "imagemagick") else: anim_fname = image.replace(".fits", ".mp4") ani.save(anim_fname, fps = fps, dpi = 100, extra_args=['-vcodec', 'libx264']) return anim_fname
def process(infile, coords, fwhmpsf, sigma, aperture, annulus, dannulus, output, zmag, debug): """ 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 fwhmpsf : float FWHM of the stelar psf in pixels sigma : float Sky background sigma annulus : int Inner sky annulus radius in pixels dannulus : int Radius of sky annulus in pixels output : string Output file name zmag : string Photometric zero point Returns ------- None """ print "PHOTOMETRY: CHIMERA Aperture Photometry Routine" fwhmpsf = float(fwhmpsf) sigma = float(sigma) annulus = int(annulus) dannulus = int(dannulus) # 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): raise IOError("PHOTOMETRY: Not able to locate file %s. Stopping." %infile) image_cubes = [] with open(infile, "r") as fd: for line in fd.readlines(): if len(line) > 1: image_cubes.append(line.replace("\n", "")) else: image_cubes = infile.split(",") # Number of images ncubes = len(image_cubes) # Check if the input coordinates file exists. Take a tmp copy of the input # file and use that. Delete at the end of processing. if not os.path.exists(coords): raise IOError("Input coordinate file %s does not exist. Stopping." %coords) else: tmp_coords = coords + ".tmp" iraf.copy(coords, tmp_coords) # Fields to extract from phot file fields = "XCEN,YCEN,CIER,MSKY,STDEV,NSKY,SIER,SUM,AREA,FLUX,MERR,PIER" total_phot_data = [] img_sec = [] for i in range(ncubes): sci_file = image_cubes[i] if not os.path.exists(sci_file): raise IOError("FITS image %s does not exist. Stopping." %sci_file) fpath, fname = os.path.split(sci_file) print "\n Processing science image %s" %fname # Instantiate an Aperphot object ap = chimera.Aperphot(sci_file, coords) # Set fwhmpsf, sigma, annulus. dannulus and zero point ap.fwhmpsf = fwhmpsf ap.sigma = sigma ap.annulus = annulus ap.dannulus = dannulus if zmag != "": ap.zmag = float(zmag) # Read the input FITS image if i == 0: img, imghdr = chimera.fitsread(ap.sci_file, header = True) else: img = chimera.fitsread(ap.sci_file) # Determine nominal aperture radius for photometry if i == 0: if aperture: nom_aper = float(aperture) else: nom_aper = ap.daocog() print " Nominal aperture radius : %4.1f pixels" %nom_aper # Perform aperture photometry on all the frames dtype = [("DATETIME", "S25"),("XCEN", "f4"),("YCEN", "f4"),("CIER", "i4"),("MSKY", "f4"),("STDEV", "f4"),("NSKY", "i4"),("SIER", "i4"),("SUM", "f4"),("AREA", "f4"),("FLUX_ADU", "f4"),("FLUX_ELEC", "f4"),("FERR", "f4"),("MAG", "f4"),("MERR", "f4"),("PIER", "i4"),] phot_data = np.zeros([ap.nframes], dtype = dtype) for j in range(ap.nframes): print " Processing frame number : %d" %(j+1) outfile = sci_file.replace(".fits", "_" + str(j) + ".phot.1") ap.daophot(j+1, tmp_coords, outfile, nom_aper) objcen = dump(outfile, "XCEN,YCEN") with open(tmp_coords, "w") as fd: fd.write(objcen + '\n') aperphot_data = dump(outfile, fields).split() phot_data[j]['DATETIME'] = ap.addtime(j * ap.kintime).isoformat() phot_data[j]['XCEN'] = float(aperphot_data[0]) phot_data[j]['YCEN'] = float(aperphot_data[1]) phot_data[j]['CIER'] = int(aperphot_data[2]) phot_data[j]['MSKY'] = float(aperphot_data[3]) phot_data[j]['STDEV'] = float(aperphot_data[4]) phot_data[j]['NSKY'] = int(aperphot_data[5]) phot_data[j]['SIER'] = int(aperphot_data[6]) phot_data[j]['SUM'] = float(aperphot_data[7]) phot_data[j]['AREA'] = float(aperphot_data[8]) phot_data[j]['FLUX_ADU'] = float(aperphot_data[9]) phot_data[j]['FLUX_ELEC'] = float(aperphot_data[9]) * ap.epadu phot_data[j]['MAG'] = ap.zmag - 2.5 * np.log10(phot_data[j]['FLUX_ELEC']/ap.exptime) if aperphot_data[10] == 'INDEF': phot_data[j]['MERR'] = -10 else: phot_data[j]['MERR'] = float(aperphot_data[10]) phot_data[j]['PIER'] = int(aperphot_data[11]) # Calculate error in flux - using the formula # err = sqrt(flux * gain + npix * (1 + (npix/nsky)) * (flux_sky * gain + R**2)) phot_data[j]['FERR'] = np.sqrt(phot_data[j]['FLUX_ELEC'] + phot_data[j]['AREA'] * (1 + phot_data[j]['AREA']/phot_data[j]['NSKY']) * (phot_data[j]['MSKY'] * ap.epadu + ap.readnoise**2)) # Save a 51x51 image section of the object xmin, xmax = int(phot_data[j]['XCEN']) - 25, int(phot_data[j]['XCEN']) + 25 ymin, ymax = int(phot_data[j]['YCEN']) - 25, int(phot_data[j]['YCEN']) + 25 img_sec.append(img[j, ymin:ymax, xmin:xmax]) # Save photometry of all the image cubes in a single file total_phot_data.append(phot_data) # If debug mode - # 1. save DAOPHOT phot files # 2. save individual phot data as npy file # 3. Plot light cuve for each data cube separatly if debug: # Save photometry data in numpy binary format print " Saving photometry data as numpy binary" if output != "": npy_outfile = output + ".npy" else: npy_outfile = coords + "_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 = coords + "_lc.png" plotter(phot_data, ap.nframes, ap.kintime, plt_outfile) else: # Delete intermediate files is not debug mode iraf.delete(os.path.join(fpath, '*.phot.1')) # Convert the total_phot_data to array and reshape it print ' Saving consolidated photometry data...' total_phot_data_arr = np.concatenate(total_phot_data) # Save the array as npy file np.save(coords + "_total.phot.npy", total_phot_data_arr) # Save the image section with object as FITS file print ' Saving image section with object as FITS image...' img_sec_arr = np.asarray(img_sec) img_fname = coords + "_obj.fits" if os.path.exists(img_fname): os.remove(img_fname) chimera.fitswrite(img_sec_arr, coords + "_obj.fits", header = imghdr) # Delete temporary coordinate file if os.path.exists(tmp_coords): os.remove(tmp_coords) return