def subtract_stars(args): """ Routine to subtract a set of stars defined by the user. We will model the PSF of some suitable stars in the images, then use that """ # First substitute the names of the image in args.image by the corresponding astroim object, with more information args.image = astroim.Astroim(args.image) # Do photometry on the stars to be used to model the PSF phot_modstars, phot_subtstars = apply_phot(args) pst_file = apply_pst(args, phot_modstars) psf_file = apply_psf(args, phot_modstars, pst_file) hdr = args.image.header # for short seeing, sigma = utils.get_from_header(args.image.im_name, hdr.seeingk, hdr.sigmak) utils.if_exists_remove(args.output) iraf.allstar( args.image.im_name, photfile=phot_subtstars, psfimage=psf_file, subimage=args.output, psfrad=6 * seeing, fitrad=3 * seeing, wcsin="physical", fitsky="yes", sannulus=4 * seeing, wsannulus=3 * seeing, verify="no", )
def _get_photometry(self): """ Get the photometry for the target. If the target is a standard star, aperture photometry will be performed. For the moment nothing is done with the others, but in due time (TODO) photometry.py will be included here. """ basename = "standards" fd, coords_file = tempfile.mkstemp(prefix=basename, suffix=".coords") os.write(fd, "{0} {1} \n".format(self.RA, self.DEC)) os.close(fd) if self.objtype == "standard": iraf.noao(_doprint=0) iraf.digiphot(_doprint=0) iraf.apphot(_doprint=0) seeing = self.header.hdr[self.header.seeingk] photfile_name = self.header.im_name + ".mag.1" utilities.if_exists_remove(photfile_name) kwargs = dict(output=photfile_name, coords=coords_file, wcsin='world', fwhm=seeing, gain=self.header.gaink, exposure=self.header.exptimek, airmass=self.header.airmassk, annulus=6*seeing, dannulus=3*seeing, apert=2*seeing, verbose="no", verify="no", interac="no") iraf.phot(self.header.im_name, **kwargs) [counts] = iraf.module.txdump(photfile_name, 'FLUX', 'yes', Stdout=subprocess.PIPE) utilities.if_exists_remove(coords_file) return float(counts)
def combine_images(args): """ Combine images using the wcs in their headers to match the pixels. :param args: :return: """ utilities.if_exists_remove(args.output) input_names = ",".join(args.input) # Unfortunately the mean is considered the only average in IRAF... (sic!) if args.average == "mean": args.average = "average" iraf.imcombine(input_names, output=args.output, scale=args.scale.lower(), combine=args.average.lower(), offsets="wcs")
def match(args): """ Match the PSF of a group of images with the PSF of a reference image. """ sort_by_seeing(args) # Get seeing from header and calculate psf of reference image, the first one since we sorted the input ref_seeing = utils.get_from_header(args.input[0], args.FWHM_key) ref_psf = psf.main(arguments=[args.input[0], "--stars", args.input_stars[0], "--sigma_key", args.sigma, "--gain_key", args.gain_key, "--ron_key", args.ron_key, "--expt_key", args.expt_key, "--airm_key", args.airm_key, "--FWHM_key", args.FWHM_key]) output_list = [] for image, stars in zip(args.input, args.input_stars): output = utils.add_suffix_prefix(image, suffix=args.suffix) # Too small differences of seeing are not worh doing any matching current_seeing = utils.get_from_header(image, args.FWHM_key) if abs(ref_seeing - current_seeing) < args.limit: # Not worth equating PSFs for small differences shutil.copy(image, output) # copy old file into new one else: # Calculate psf of the other images psf_object = psf.main(arguments=[image, "--stars", stars, "--sigma_key", args.sigma, "--gain_key", args.gain_key, "--ron_key", args.ron_key, "--expt_key", args.expt_key, "--airm_key", args.airm_key, "--FWHM_key", args.FWHM_key]) utils.if_exists_remove("kernel.fits", output) iraf.psfmatch(image, ref_psf, psf_object, "kernel.fits", convolution="psf", filter="cosbell") iraf.psfmatch(image, ref_psf, psf_object, convolution="kernel", kernel="kernel.fits", output=output, verbose="no") utils.if_exists_remove("kernel.fits") mssg = "Before equating PSFs: " + str(current_seeing) utils.header_update_keyword(output, args.FWHM_key, ref_seeing, comment=mssg) output_list.append(output) return output_list
def psf(args): """ Calculate the PSF of an image. """ # Load iraf packages: phot, pstselect, psf will be needed iraf.noao(_doprint=0) iraf.digiphot(_doprint=0) iraf.module.daophot(_doprint=0) # Read the seeing and sigma of the sky from the header seeing, sigma = utils.get_from_header(args.input, args.FWHM_key, args.sigma) # Do photometry on the image #print "photometry: \n" photfile_name = args.input + ".mag.1" utils.if_exists_remove(photfile_name) iraf.module.phot(args.input, output=photfile_name, coords=args.stars, wcsin=args.coords, fwhm=seeing, sigma=sigma, datamax=args.maxval, datamin=args.minval, ccdread=args.ron_key, gain=args.gain_key, exposure=args.expt_key, airmass=args.airm_key, annulus=6*seeing, dannulus=3*seeing, apert=2*seeing, verbose="no", verify="no", interac="no") # Select stars on the image #print "pstselect: \n" pstfile_name = args.input + ".pst.1" utils.if_exists_remove(pstfile_name) iraf.module.pstselect(args.input, photfile=photfile_name, pstfile=pstfile_name, maxnpsf=20, fwhm=seeing, sigma=sigma, datamax=args.maxval, ccdread=args.ron_key, gain=args.gain_key, exposure=args.expt_key, function="auto", nclean=1, psfrad=2*seeing, fitrad=seeing, maxnstar=20, verbose="no", verify="no") # Build psf of the stars #print "psf: \n" psffile_table = args.input + ".psf.1.fits" # iraf keeps adding the .fits :( psgfile_name = args.input + ".psg.1" pstfile_name2 = args.input + ".pst.2" utils.if_exists_remove(psffile_table,psgfile_name, pstfile_name2) iraf.module.psf( args.input, photfile=photfile_name, pstfile=pstfile_name, groupfile=psgfile_name, opstfile=pstfile_name2, psfimage=psffile_table,fwhm=seeing, sigma=sigma, datamax=args.maxval, datamin=args.minval, ccdread=args.ron_key, gain=args.gain_key, exposure=args.expt_key, function="moffat25", nclean=1, psfrad=12, fitrad=seeing, maxnstar=20, interactive="no", varorder=-1, verbose="no",verify="no") # Use seepsf to build the image of the psf psffile_name = args.input + ".psf.fits" utils.if_exists_remove(psffile_name) iraf.module.seepsf(psffile_table, psffile_name) return psffile_name
def _get_photometry(self, seeing=None, aperture=None): """ Get the photometry for the target. If the target is a standard star, aperture photometry will be performed. For the moment nothing is done with the others, but in due time (TODO) photometry.py will be included here. """ if self.objtype is not "standards": return None basename = "standards" fd, coords_file = tempfile.mkstemp(prefix=basename, suffix=".coords") os.write(fd, "{0} {1} \n".format(self.RA, self.DEC)) os.close(fd) # If aperture was not given by the user, try and use the seeing as a reference for default values if not aperture: try: seeing = self.header.hdr[self.header.seeingk] aperture = 3 * seeing except ValueError: # keyword was not correctly guessed pass # If aperture exists, do the photometry using it if aperture: annulus = 2 * aperture dannulus = max([aperture, 3]) # minimum of 3 pixels thickness for the sky annulus fd, photfile_name = tempfile.mkstemp(".mag.1") utilities.if_exists_remove(photfile_name) kwargs = dict(output=photfile_name, coords=coords_file, salgorithm='median', wcsin='world', fwhm=seeing, gain=self.header.gaink, exposure=self.header.exptimek, airmass=self.header.airmassk, annulus=annulus, dannulus=dannulus, apertures=aperture, verbose="no", verify="no", interac="no") iraf.phot(self.header.im_name, **kwargs) [counts] = iraf.txdump(photfile_name, 'FLUX', 'yes', Stdout=subprocess.PIPE) else: sys.exit("\n \n Sorry, no aperture was passed by you, and a seeing keyword was not " "found in the header. \n\n ") utilities.if_exists_remove(coords_file) return float(counts)
def calculate_seeing(args): """ Program to estimate the seeing from an image and a list of estimates for the positions of stars. After calculating the seeing, some of the stars might get recalculated centers. The list will be updated with the """ for im, im_cat in zip(args.input, args.cat): output = "output.txt" ignore = "ignore.txt" # Victor Terron, esto es horroroso, sugerencias? utilities.if_exists_remove("q.txt", output, ignore) q = open("q.txt", "w") q.write("q") q.close() iraf.noao() iraf.obsutil() iraf.module.psfmeasure(im, coords = "mark1", size = "MFWHM", sbuffer = 10, swidth=10,radius=10, satura = 55000, ignore = "yes", imagecur = im_cat, display = "no", graphcur = "q.txt", Stdout=ignore, wcs = args.wcs, logfile=output) # Now we read the input im_cat and the output output.txt and compare # the location of stars. Those stars that have moved will not be # trusted. xout = np.array([]) yout = np.array([]) FWHM = np.array([]) for line in open(output, 'r'): # First line is a description of the file, second is a newline \n # and third the description of the columns. if line != "\n" and line.split()[0] in im: xout = np.append(xout, float(line.split()[1])) yout = np.append(yout, float(line.split()[2])) FWHM = np.append(FWHM, float(line.split()[4])) else: try: xout = np.append(xout, float(line.split()[0])) yout = np.append(yout, float(line.split()[1])) FWHM = np.append(FWHM, float(line.split()[3])) except: pass xin, yin = np.genfromtxt(im_cat, dtype="float", unpack=True) xin, yin = np.array(xin), np.array(yin) # case it is only one value # If args.wcs is "world" it means the input is in (RA, DEC), while # the output is in pixels (X,Y). We need to convert one to the other # and we choose to follow the (RA,DEC) which, after all, is meaningful if args.wcs == "world": coords_xy = np.array(zip(xout, yout)) hdr = fits.open(im)[0].header remove_keys = ["PC001001", "PC001002", "PC002001", "PC002002"] for keys in remove_keys: hdr.pop(keys,None) w = wcs.WCS(hdr) coords_RADEC = w.all_pix2world(coords_xy,1) xout = coords_RADEC[:,0] yout = coords_RADEC[:,1] # find common stars using KDtrees if xin.size > 1 : tree_in = spatial.KDTree(zip(xin, yin)) elif xin.size == 1: tree_in = spatial.KDTree([(float(xin), float(yin))]) if xout.size > 1: tree_out = spatial.KDTree(zip(xout, yout)) elif xout.size == 1: tree_out = spatial.KDTree([(float(xout), float(yout))]) # If WCS use 0.001 degree (~3.6 arcsec) as limit. If not, assume # pixels and say 4 pixels if args.wcs == "world": limit = 0.001 else: limit = 4 matches = tree_out.query_ball_tree(tree_in, limit) # Two close stars in the original .cat could resolve into one when # the FWHM is calculated. This will appear as several hits in the # matches with exactly the same numbers: [[0], [1,2], [1,2], [3]] # One solution is to erase one of them for index, value in enumerate(matches): if matches.count(value) > 1: matches[index] = [] # Now restrict to the common objects remove_indices = [ii for ii,jj in enumerate(matches) if jj == []] xout = np.delete(xout, remove_indices) yout = np.delete(yout, remove_indices) FWHM = np.delete(FWHM, remove_indices) # Finally, calculate the median FWHM of the image and rewrite valid # stars to the im_cat file. median_fwhm = np.median(FWHM) utilities.header_update_keyword(im, "seeing", median_fwhm, "FWHM of image") f = open(im_cat, 'w') # write the "good" stars in the catalogue for ii in range(len(xout)): f.write(str(xout[ii]) + " " + str(yout[ii]) + "\n") f.close() # And clean after yourself! utilities.if_exists_remove("q.txt", output, ignore)
"(?P<filt>.*)_(?P<exp_num>\d{3})(?P<rest>.*-c\.fits)$" in_pattern["blanks"] = "^(?P<name>blank)_(?P<date>\d{8})_(?P<filt>.*)_" +\ "(?P<exp_num>\d{3})(?P<rest>.*-c\.fits)$" list_images = utilities.locate_images2(dir, in_pattern) return list_images list_images = search_images(directory) print "For each object and filter, do photometry on all images" AllObj_set = set(x for x,t in zip(list_images["objname"], list_images["type"]) if t in ["standards", "cig", "clusters"]) for obj in AllObj_set: # for each of the standards obj_images = list(list_images["filename"][np.where( (list_images["objname"] == obj))]) output_db = os.path.join(directory, obj+".db") utilities.if_exists_remove(output_db) coord_file = utilities.replace_extension(obj_images[0], "radec") photometry.main(arguments=["--maximum", str(max_counts), "--uik", "", "--margin", "20", "--gaink", gaink, "--aperture", "4.", "--annulus", "6", "--dannulus", "2", "--individual-fwhm", "--objectk", objectk, "--filterk", filterk, "--datek", datek, "--expk", exptimek, "--fwhmk", seeingk, "--airmk", airmassk, "--coordinates", coord_file, obj_images[0]] + obj_images + [output_db]) print "Find extinction coefficient from photometry of standards" standards_set = set(x for x,t in zip(list_images["objname"], list_images["type"]) if t == "standards") coefficient_list = [] for obj in standards_set: input_db = os.path.join(directory, obj+".db") airmasses, magnitudes, filters, SNR = extract.main(input_db) magnitude_errors_minus, magnitude_errors_plus = snr.snr_to_error(SNR) mag_errors = (-magnitude_errors_minus + magnitude_errors_plus) / 2. for filt in set(filters.flatten()):