def trim(args): # Define region to be trimmed y0, y1, x0, x1 = args.region # args.output should be a list of output names. If they do not exist, the outputs should be the same as the # inputs with whatever suffix, if any, the user gave if not args.output: args.output = [utilities.add_suffix_prefix(im_name, suffix=args.suffix) for im_name in args.input] # Do the actual trimming. We will do it first into a temporary file, then copy it into args.output. This is just # in case the output and input filenames are the same, or if the output exists. IRAF will not overwrite! for im_name, new_name in zip(args.input, args.output): basename = os.path.splitext(os.path.basename(im_name))[0] _, temp_output = tempfile.mkstemp(prefix=basename, suffix=".fits") os.unlink(temp_output ) with utilities.tmp_mute(): imcopy(im_name + "[{0}:{1}, {2}:{3}]".format(x0, x1, y0, y1), temp_output) shutil.move(temp_output, new_name) # If a mask exists, trim exactly equally if args.mask_key: maskname = fits.getheader(im_name)[args.mask_key] with fits.open(maskname, 'readonly') as mask_im: mask_im[0].data = mask_im[0].data[y0:y1+1, x0:x1+1] mask_output = utilities.replace_extension(new_name, ".fits.msk") fits.writeto(mask_output, mask_im[0].data, mask_im[0].header, clobber=True) utilities.header_update_keyword(new_name, "MASK", os.path.abspath(mask_output), comment="Name of mask image. ") return args.output
def mask(args): for image, output in zip(args.image, args.output): im = astroim.Astroim(image) # If mask does not exist if not im.mask_name: im.HDUList_mask = build_mask(im) im.mask_name = utils.replace_extension(im.im_name, ".fits.msk") im.chips = im._get_chips() im._copy_wcs_to_mask() im = minmax_mask(im, min_val=args.minval, max_val=args.maxval, mask_value=args.false_val) # If circular field of view within rectangular image: if args.circular: im = mask_circular(im, mask_value=args.outside_val, margin=args.margin) # Star masking fitting sky if args.stars: # if stars in the image im = max_sigma_clip(im, n_sigma=3, mask_value=args.false_val) # Save mask image im.HDUList_mask[0].header.add_comment("Mask for image {0}".format(image)) im.HDUList_mask.writeto(output, clobber=True) # Include comment in the header im.primary_header.hdr["MASK"] = output im.write() return None
def main(im_name, ra=None, dec=None, FoV=None): if ra == None or dec == None: if FoV == None: FoV = 20 # Largest image I've seen, 20 degrees, just in case # User passed the keywords? try: ra, dec = utilities.get_from_header(im_name, ra, dec) argunents = ["--ra", ra, "--dec", dec, "--radius", float(FoV)/2.] except KeyError: arguments = [] # User passed the numbers try: ra, dec = float(ra), float(dec) argunents = ["--ra", ra, "--dec", dec, "--radius", float(FoV)/2.] except ValueError: arguments = [] arguments = arguments + ["solve-field", "--no-plots", "--no-fits2fits", "--use-sextractor", "--code-tolerance", "0.01", "--overwrite", im_name] subprocess.call(arguments) # Sort things out, clean up... solved = utilities.replace_extension(im_name, "solved") output_name = utilities.replace_extension(im_name, "new") assert os.path.exists(output_name) shutil.move(output_name, im_name) # Update old WCS system PC matrices and so on to avoid confusion utilities.update_WCS(im_name, im_name) # Build a catalogue with the coordinates of the stars found in # X and Y, RA and DEC and the flux of the stars corr_file = utilities.replace_extension(im_name, "corr") table = fits.open(corr_file)[1] cat_radec = utilities.replace_extension(im_name, "radec") f = open(cat_radec, "w") for line in table.data: f.write(str(line[2]) + " " + str(line[3]) + "\n") f.close()
def main(arguments = None): # Pass arguments to variable args if arguments == None: arguments = sys.argv[1:] args = parser.parse_args(arguments) if not args.output: args.output = [utils.replace_extension(im, ".fits.msk") for im in args.image] # True_val and false_val can not be the same if args.true_val == args.false_val: sys.exit("\n\n ERROR: true_val and false_val are the same value: " + \ str(args.false_val) + " Use --true_val and --false_val \n\n") # Call combine, keep name of the file created masknames = mask(args) return masknames
def main(arguments = None): # Pass arguments to variable args if arguments == None: arguments = sys.argv[1:] args = parser.parse_args(arguments) # Option 1: the user did not provide any catalogues, because they are named like the images, but with '.radec' extension # Option 2: the user provided a single catalogue, because all the images contain the same object # Option 3: the user provided an invalid number of catalogues for the number of images. if args.cat is None: args.cat = [utilities.replace_extension(im_name, ".radec") for im_name in args.input] if not all([os.path.exists(cat_name) for cat_name in args.cat]): sys.exit("Catalogues not found! Check the --cat option in the description: type estimate_seeing.py -h") elif len(args.cat) == 1: args.cat *= len(args.input) elif len(args.input) != len(args.cat): sys.exit("\n\n number of star catalogues and input images do not coincide \n ") calculate_seeing(args) return None
def main(Ha_name, rgunn_name, scaling_factor, zp_Ha, T_Ha, T_rGunn): # Tell the user to load regions for the galaxy galaxy_messg = "\n Create/load region(s) in ds9 to enclose the galaxy. "+\ " Save it for latter use. Then hit the 'OK' button!" galaxy_region = mask_from_ds9(rgunn_name, galaxy_messg) # Sky regions sky_messg = "\n Now do the same for sky region (or regions!) " sky_region = mask_from_ds9(rgunn_name, sky_messg) # Stars to model PSF mod_stars_catalogue = utils.replace_extension(rgunn_name, ".model_stars") mod_stars_messg = "\n Select nice isolated non-saturated stars to model the PSF. " mod_stars_region = positions_of_stars_from_ds9(rgunn_name, mod_stars_messg, mod_stars_catalogue) # Stars to be subtracted subt_stars_catalogue = utils.replace_extension(rgunn_name, ".subt_stars") subt_stars_messg = "\n Finally, select the stars to be subtracted from the images" subt_stars_region = positions_of_stars_from_ds9(rgunn_name, subt_stars_messg, subt_stars_catalogue) # Now remove the stars from the images output_Ha = utils.add_suffix_prefix(Ha_name, suffix='-s') extract_stars.main(arguments=['--model_stars', mod_stars_catalogue, "--subt_stars", subt_stars_catalogue, '--coords', 'world', '--output', output_Ha, Ha_name]) output_rgunn = utils.add_suffix_prefix(rgunn_name, suffix='-s') extract_stars.main(arguments=['--model_stars', mod_stars_catalogue, "--subt_stars", subt_stars_catalogue, '--coords', 'world', '--output', output_rgunn, rgunn_name]) # Read images image_Ha = fits.open(output_Ha) Ha_data = np.array(image_Ha[0].data, dtype=np.float64) Ha_header = image_Ha[0].header Ha_shape = Ha_data.shape image_R = fits.open(output_rgunn) R_data = np.array(image_R[0].data, dtype=np.float64) R_header = image_R[0].header R_shape = R_data.shape # Halpha image: get galaxy mask, sky mask, subtract sky from galaxy flux Ha_gal_mask = galaxy_region.as_imagecoord(Ha_header).get_mask(shape=Ha_shape) Ha_sky_mask = sky_region.as_imagecoord(Ha_header).get_mask(shape=Ha_shape) Ha_sky_flux = np.median(Ha_data[Ha_sky_mask == 1]) Ha_data_nosky = Ha_data - Ha_sky_flux Ha_and_R_counts = np.sum( Ha_data_nosky[Ha_gal_mask == 1]) print "Narrow Ha filter counts: ", Ha_and_R_counts # Same for R image: get galaxy mask, sky mask, subtract sky from galaxy flux R_gal_mask = galaxy_region.as_imagecoord(R_header).get_mask(shape=R_shape) R_sky_mask = sky_region.as_imagecoord(R_header).get_mask(shape=R_shape) R_sky_flux = np.median(R_data[R_sky_mask == 1]) R_data_nosky = R_data - R_sky_flux R_counts = np.sum( R_data_nosky[R_gal_mask == 1]) print "R filter counts: ", R_counts # Halpha is basically the subtractiong of the counts in Halpha filter minus the scaled R counts # but more precisely, the contrinbution of Halpha line to the filter rGunn should be corrected. # For: # - a transmittance T(Gunn) of redshifted Halpha in the rGunn filter # - T(Ha_filter) the transmittance of redshifted Halpha in the Halpha narrow filter # - scaling_factor the factor of scale between counts in filter rGunn and in the Ha filter (typically from stars) # - rgunn_scaled the number of counts in the Gunn filter, already scaled to match Halpha # - Ha_filter is the counts in the narrow Ha filter, which obviously contain a contribution from R. # - Halpha the number of counts of the Halpha line in the Halpha filter (the contribution of Halpha alone) # # we would need to subtract the Halpha contribution to rGunn before we scale it, but since we are starting # already from a scaled version of rGunn, we need to divide the contribution from Halpha by the scaling factor. # The system of equations would be: # # R_counts = rgunn_scaled - Halpha * T(Gunn)/T(Ha_filter) / scaling_factor # Halpha = Ha_filter - R_counts # # with solution: # Halpha = (Ha_filter - rgunn_scaled) * scaling_factor/(scaling_factor - T(Gunn)/T(Halpha) # # which gives, for a typical scaling factor of ~11 and similar transmittances in both filters a correction # of the order of ~10%. Halpha = (Ha_and_R_counts - R_counts * scaling_factor) / (1 - scaling_factor * T_rGunn / T_Ha) print "Halpha counts: ", Halpha print Halpha / T_Ha * 10**(-zp_Ha/2.5) mask = np.logical_or(Ha_gal_mask, Ha_sky_mask) d = ds9.ds9() d.set_np2arr(Ha_data * mask, dtype=np.float64)
for index, image in enumerate(list_images["filename"]): if list_images["type"][index] in ("cig", "standards", "clusters"): # Victor Terron has promissed changing dirs will soon be unnecessary curdir = os.path.abspath(os.curdir) os.chdir(lemon_dir) import lemon.seeing as seeing seeing.main(arguments=["--margin", "0", "--filename", '', "--suffix", "-s", image, os.path.split(image)[0] ]) newname = utilities.add_suffix_prefix(image, suffix = "-s") os.chdir(curdir) list_images["filename"][index] = newname # While running lemon.seeing a sextractor catalogue is produced. catalog = fits.getheader(newname)["SEX CATALOG"] catalog_newname = utilities.replace_extension(newname, ".cat") shutil.copy(catalog, catalog_newname) # Damn FITS format and its constraints! short_name = os.path.split(catalog_newname)[1] utilities.header_update_keyword(newname, "SEX CATALOG", short_name) print "Estimate sky for images of CIG(s), standard(s) and cluster(s) " for index, image in enumerate(list_images["filename"]): if list_images["type"][index] in ["cig","standards","clusters"]: find_sky.main(arguments=[list_images["filename"][index]]) print "Detecting objects for images of CIG(s), standard(s) and cluster(s)" # This part follows the example in the webpage: #http://www.lancesimms.com/programs/Python/pyraf/daofind.py for index, image in enumerate(list_images["filename"]): if list_images["type"][index] in ["cig","standards","clusters"]:
def include_wcs(args): # Copy input names into output names output_names = args.input[:] for ii, im_name in enumerate(args.input): # If it is a domeflat, skyflat or bias image, calculating the astrometry makes little sense im = astroim.Astroim(im_name) if im.target.objtype in ["bias", "domeflat", "skyflat", "flat"]: continue # Prepare my output file for the resulting image if args.suffix: new_file = utilities.add_suffix_prefix(im_name, suffix=args.suffix) elif args.overwrite: new_file = im_name # Copy input image into a temporary file, so that we can modify it freely, for example, remove cosmics # or filter it (to be done). basename = get_basename(im_name) _, input_image = tempfile.mkstemp(prefix=basename, suffix=".fits") shutil.copy2(im_name, input_image) # Remove cosmics if args.cosmics: perform_cosmic_removal(input_image) # The output of the WCS process of astrometry.net will go to a .new file, the coordinates to a .coor output_wcs = utilities.replace_extension(input_image, ".new") solved_file = utilities.replace_extension(input_image, ".solved") corrfile = utilities.replace_extension(input_image, ".cor") # Try first with the defaults of astrometry arguments_def = ["solve-field", "--no-plots", "--no-fits2fits", "--dir", "/tmp", "--overwrite", "--new-fits", output_wcs, "--corr", corrfile, "--cpulimit", "1", input_image] try: # Try to add the RA, DEC, Radius options to constrain the search ra, dec = im.primary_header.get(im.primary_header.RAk, im.primary_header.DECk) ra, dec = utilities.sex2deg(ra, dec) arguments = arguments_def + ["--ra", str(ra), "--dec", str(dec), "--radius", str(args.radius), "--cpulimit", "20"] except: arguments = arguments_def print "Trying to find WCS with astrometry standard keywords. " with utilities.tmp_mute(): subprocess.call(arguments) # Now we will try using sextractor build_default_sex(args) # To avoid having too much residual crap in the folder, the output of astrometry will go to tmp (--dir /tmp). arguments0 = ["solve-field", "--no-plots", "--no-fits2fits", "--use-sextractor", "--dir", "/tmp", "--x-column", "X_IMAGE", "--y-column", "Y_IMAGE", "--sort-column", "MAG_AUTO", "--sort-ascending", "--sextractor-config", os.path.join(repipy_path, "default.sex"), "--overwrite", "--new-fits", output_wcs, "--corr", corrfile, input_image] arguments0 += args.extras try: # Try to add the RA, DEC, Radius options to constrain the search ra, dec = im.primary_header.get(im.primary_header.RAk, im.primary_header.DECk) ra, dec = utilities.sex2deg(ra, dec) arguments = arguments0 + ["--ra", str(ra), "--dec", str(dec), "--radius", str(args.radius), "--cpulimit", "20"] except: arguments = arguments0 # Run astrometry, in case of not solving it on the first attempt, try fitting freely (no RA, DEC used) if not os.path.exists(solved_file): subprocess.call(arguments) if not os.path.exists(solved_file): subprocess.call(arguments0) # Only if we have a solution if os.path.exists(solved_file): # copy the input file into the new file if they are not the same if os.path.abspath(im_name) != os.path.abspath(new_file): shutil.copy2(im_name, new_file) # get WCS from the resulting file, only the part added by astrometry.net with fits.open(output_wcs) as file_wcs: hdr_wcs = file_wcs[0].header ind = hdr_wcs.values().index('Original key: "END"') # new part added by astrometry hdr_wcs = hdr_wcs[ind:] # Add that header to the original one of the image with fits.open(new_file, 'update') as new_im: new_im[0].header += hdr_wcs new_im.flush() # Build a catalogue of RA, DEC for the stars found with fits.open(corrfile) as table: cat_radec = utilities.replace_extension(new_file, "radec") with open(cat_radec, "w") as f: for ra, dec in zip(table[1].data["field_ra"], table[1].data["field_dec"]): f.write(str(ra) + " " + str(dec) + "\n") output_names[ii] = new_file # If --remove_original is True if args.remove_orig and not args.overwrite: os.unlink(im_name) return output_names
if list_images["type"][index] in ["cig", "standards", "clusters"]: # Get date, RA, DEC from images. time, RA_current, DEC_current = utilities.get_from_header(im, datek, rak,deck) RA, DEC = utilities.precess_to_2000(RA_current, DEC_current, time) RA, DEC, radius = str(RA), str(DEC), str(FoV/2.5) # Calculate WCS using sextractor subprocess.call(["solve-field", "--no-plots", "--no-fits2fits", "--ra", RA, "--dec", DEC, "--radius", radius, "--depth", "1-30", "--depth", "1-50", "--depth", "1-100", "--depth", "10,20,30,40,50,60,70,80,90,100", "--use-sextractor", "--code-tolerance", "0.01", "--overwrite", im]) solved = utilities.replace_extension(im, "solved") # Case sextractor couldn't do it, try with astrometry.net's own routine if not os.path.exists(solved): subprocess.call(["solve-field", "--no-plots", "--no-fits2fits", "--ra", RA, "--dec", DEC, "--radius", radius, "--depth", "1-30", "--depth", "1-50", "--depth", "1-100", "--depth", "10,20,30,40,50,60,70,80,90,100", "--code-tolerance", "0.002", "--overwrite", im]) output_name = utilities.replace_extension(im, "new") shutil.move(output_name, im) # Update old WCS system PC matrices and so on to avoid confusion utilities.update_WCS(im, im)
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()): # find columns with the current filter