def make_reference(files, reg, params, reference_image='ref.fits'): seeing = {} sky = {} ref_seeing = 1000 # # Have we specified the files to make the reference with? # if params.ref_include_file: ref_list = [] for line in open(params.ref_include_file, 'r'): for f in files: if f.name == line.split()[0]: ref_list.append(f) print f.name, f.fw, f.signal if f.fw < ref_seeing: ref_sky = f.sky ref_seeing = f.fw best_seeing_ref = f else: # # We try to choose the best images # reference_exclude = [] if params.ref_exclude_file: for line in open(params.ref_exclude_file, 'r'): reference_exclude.append(line.split()[0]) sig = [] for f in files: sig.append(f.signal) sig = np.asarray(sig) sigcut = np.mean(sig) - 2.0 * np.std(sig) print 'signal: mean, std, cut = ', np.mean(sig), np.std(sig), sigcut print 'Searching for lowest-background image' ref_sky = 1.e6 for f in files: print f.name, f.fw, f.sky, f.signal if (f.sky < ref_sky) and (f.fw > params.reference_min_seeing) and \ (f.roundness < params.reference_max_roundness) and (f.signal > sigcut) and not(f.name in reference_exclude): ref_sky = f.sky ref_sky = np.max([ref_sky, params.pixel_max / 1.e5]) print 'Searching for best-seeing image' ref_seeing = 100.0 for f in files: print f.name, f.fw, f.sky, f.signal if (f.fw < ref_seeing) and (f.fw > params.reference_min_seeing) and \ (f.roundness < params.reference_max_roundness) and (f.signal > sigcut) and not(f.name in reference_exclude): ref_seeing = f.fw best_seeing_ref = f ref_list = [] while len(ref_list) < params.min_ref_images: ref_list = [] print 'Reference FWHM = ', ref_seeing print 'Cutoff FWHM for reference = ', params.reference_seeing_factor * ref_seeing print 'Cutoff background for reference = ', params.reference_sky_factor * ref_sky print 'Combining for reference:' for f in files: if (f.fw < params.reference_seeing_factor*ref_seeing) and \ (f.roundness < params.reference_max_roundness) and (f.sky < params.reference_sky_factor*ref_sky) and \ (f.fw > params.reference_min_seeing) and (f.signal > sigcut) and not(f.name in reference_exclude): ref_list.append(f) print f.name, f.fw, f.sky, f.signal params.reference_seeing_factor *= 1.02 params.reference_sky_factor *= 1.02 if len(ref_list) > params.max_ref_images: ref_list = ref_list[:params.max_ref_images] sig = [] for f in ref_list: sig.append(f.signal) sig = np.asarray(sig) sigcut = np.mean(sig) - 2 * np.std(sig) print 'signal: mean, std, cut = ', np.mean(sig), np.std(sig), sigcut ref_seeing = 1000 ref_roundness = 2.0 for f in ref_list: if (f.fw < ref_seeing) and (f.signal > sigcut): ref_sky = f.sky ref_seeing = f.fw ref_roundness = f.roundness best_seeing_ref = f # # Which ref image has the worst seeing? # worst_seeing = 0.0 for f in ref_list: if f.fw > worst_seeing: worst_seeing = f.fw worst_seeing_ref = f if params.ref_image_list: with open(params.loc_output + os.path.sep + params.ref_image_list, 'w') as fid: for f in ref_list: fid.write(f.name + ' ' + str(f.fw) + ' ' + str(f.sky) + ' ' + str(f.signal) + '\n') # # Find the locations of the brightest stars to use as stamp positions # if required # stamp_positions = None if params.use_stamps: stars = PH.choose_stamps(best_seeing_ref, params) stamp_positions = stars[:, 0:2] # # Construct the reference image. # ref = np.zeros([1, 1]) sum1 = 0 sum2 = 0 good_ref_list = [] for f in ref_list: f.blur = IM.boxcar_blur(f.image) good_ref_list.append(f) print 'difference_image:', f.name, best_seeing_ref.name if not (params.use_GPU) and (params.n_parallel > 1): # # Use ParallelProcessing to process images in the reference list # pool = Pool(params.n_parallel) results = pool.map( process_reference_image_helper, itertools.izip( ref_list, itertools.repeat((best_seeing_ref, params, stamp_positions)))) for i, f in enumerate(ref_list): f.result = results[i] else: for f in ref_list: f.result = process_reference_image( f, (best_seeing_ref, params, stamp_positions)) # # Remove bad reference models # rlist = [g for g in good_ref_list] for g in rlist: if not (isinstance(g.result.diff, np.ndarray)): print 'removing', g.name good_ref_list.remove(g) print 'good reference list:' for g in good_ref_list: print g.name print 'kappa-clipping reference list' for iterations in range(5): if len(good_ref_list) < 4: break sd = np.zeros(len(good_ref_list)) for i, g in enumerate(good_ref_list): print g.name, g.result.diff sd[i] = np.std(g.result.diff) sds = sd.std() sdm = sd.mean() rlist = [g for g in good_ref_list] for g in rlist: if np.std(g.result.diff) > (sdm + 2.5 * sds): print 'removing', g.name good_ref_list.remove(g) # # Combine the good reference models # g = good_ref_list[0] gstack = np.zeros( [len(good_ref_list), g.result.model.shape[0], g.result.model.shape[1]]) var_ref = np.zeros_like(g.result.model) mask = np.ones_like(g.result.model) print 'final reference list' for i, g in enumerate(good_ref_list): if isinstance(g.result.model, np.ndarray): print g.name, np.std(g.result.diff), np.median(g.result.model) IO.write_image(g.result.model, params.loc_output + os.path.sep + 'mr_' + g.name) gstack[i, :, :] = g.result.model var_ref += g.result.model / params.gain + (params.readnoise / params.gain)**2 mask *= g.mask rr = np.median(gstack, axis=0) IO.write_image(rr, params.loc_output + os.path.sep + reference_image) IO.write_image(mask, params.loc_output + os.path.sep + 'mask_' + reference_image) var_ref /= np.float(len(good_ref_list)) IO.write_image(var_ref, params.loc_output + os.path.sep + 'var_' + reference_image) if params.error_image_prefix is not None: IO.write_image( np.sqrt(var_ref), params.loc_output + os.path.sep + params.error_image_prefix + reference_image) for f in ref_list: f.result = None return stamp_positions
def imsub_all_fits(params, reference='ref.fits'): # # Create the output directory if it doesn't exist # if not (os.path.exists(params.loc_output)): os.mkdir(params.loc_output) # # The degree of spatial shape changes has to be at least as # high as the degree of spatial photometric scale # if (params.sdeg < params.pdeg): print 'Increasing params.sdeg to ', params.pdeg params.sdeg = params.pdeg # # Print out the parameters for this run. # print 'Parameters:' for par in dir(params): print par, getattr(params, par) print # # Determine our list of images # all_files = os.listdir(params.loc_data) all_files.sort() files = [] for f in all_files: print 'file', f if fnmatch.fnmatch(f, params.name_pattern): g = DS.Observation(params.loc_data + os.path.sep + f, params) del g.data del g.mask print 'fw', g.fw if g.fw > 0.0: files.append(g) print g.name, 'accepted' if len(files) < 3: print 'Only', len(files), 'files found matching', params.name_pattern print 'Exiting' sys.exit(0) # # Have we specified a registration template? # if params.registration_image: reg = DS.Observation(params.registration_image, params) else: reg = DS.EmptyBase() reg.fw = 999.0 for f in files: if (f.fw < reg.fw) and (f.fw > params.reference_min_seeing) and ( f.sky < params.registration_max_background): reg = f print 'Registration image:', reg.name # # Register images # print 'Registering images' files_copy = [f for f in files] for f in files: print f.name if f == reg: f.image = f.data rf = params.loc_output + os.path.sep + 'r_' + f.name IO.write_image(f.image, rf) else: if not f.register(reg, params): files_copy.remove(f) # delete image arrays to save memory del f.image del f.mask del f.inv_variance del reg.data del reg.image del reg.mask del reg.inv_variance files = files_copy # # Write image names and dates to a file # if params.image_list_file: try: with open(params.loc_output + os.path.sep + params.image_list_file, 'w') as fid: for f in files: date = None if params.datekey: date = IO.get_date( params.loc_data + os.path.sep + f.name, key=params.datekey) - 2450000 if date: fid.write(f.name + ' %10.5f\n' % date) else: fid.write(f.name) except: raise # # Make the photometric reference image if we don't have it. # Find stamp positions if required. # if not (os.path.exists(params.loc_output + os.path.sep + reference)): print 'Reg = ', reg.name stamp_positions = make_reference(files, reg, params, reference_image=reference) ref = DS.Observation(params.loc_output + os.path.sep + reference, params) mask, _ = IO.read_fits_file(params.loc_output + os.path.sep + 'mask_' + reference) variance, _ = IO.read_fits_file(params.loc_output + os.path.sep + 'var_' + reference) ref.mask = mask ref.inv_variance = 1.0 / variance ref.register(reg, params) else: ref = DS.Observation(params.loc_output + os.path.sep + reference, params) if os.path.exists(params.loc_output + os.path.sep + 'mask_' + reference): mask, _ = IO.read_fits_file(params.loc_output + os.path.sep + 'mask_' + reference) else: mask = np.ones_like(ref.data) ref.mask = mask ref.register(reg, params) stamp_positions = None if params.use_stamps: stamp_file = params.loc_output + os.path.sep + 'stamp_positions' if os.path.exists(stamp_file): stamp_positions = np.genfromtxt(stamp_file) else: stars = PF.choose_stamps(ref, params) stamp_positions = stars[:, 0:2] np.savetxt(stamp_file, stamp_positions) pm = params.pixel_max params.pixel_max *= 0.9 ref.mask *= IM.compute_saturated_pixel_mask(ref.image, params) params.pixel_max = pm ref.blur = IM.boxcar_blur(ref.image) if params.mask_cluster: ref.mask *= IM.mask_cluster(ref.image, ref.mask, params) # # Detect stars and compute the PSF if we are doing photometry # star_positions = None sky = 0.0 if params.do_photometry: star_file = params.loc_output + os.path.sep + 'star_positions' psf_file = params.loc_output + os.path.sep + 'psf.fits' if not (os.path.exists(psf_file)) or not (os.path.exists(star_file)): stars = PH.compute_psf_image(params, ref, psf_image=psf_file) star_positions = stars[:, 0:2] star_sky = stars[:, 4] if os.path.exists(star_file): star_positions = np.genfromtxt(star_file) star_sky = star_positions[:, 0] * 0.0 else: np.savetxt(star_file, star_positions) print 'sky =', sky # # If we have pre-determined star positions # if params.star_file: stars = np.genfromtxt(params.star_file) star_positions = stars[:, 1:3] if params.star_reference_image: star_ref, h = IO.read_fits_file(params.star_reference_image) offset, _, _ = register_translation(star_ref, ref.image, 1000) dy, dx = offset #dy, dx = IM.positional_shift(ref.image,star_ref) print 'position shift =', dx, dy star_positions[:, 0] -= dx star_positions[:, 1] -= dy np.savetxt(star_file, star_positions) # # If we are using a CPU, group the stars by location # print 'Group_check' print 'params.do_photometry', params.do_photometry print 'params.use_GPU', params.use_GPU if params.do_photometry: star_group_boundaries = None detector_mean_positions_x = None detector_mean_positions_y = None star_unsort_index = None star_sort_index,star_group_boundaries,detector_mean_positions_x,detector_mean_positions_y = \ PH.group_stars_ccd(params,star_positions,params.loc_output+os.path.sep+reference) star_positions = star_positions[star_sort_index] star_sky = star_sky[star_sort_index] star_unsort_index = np.argsort(star_sort_index) # # Do photometry of the reference image # if params.do_photometry: ref_flux_file = params.loc_output + os.path.sep + 'ref.flux' if not (os.path.exists(ref_flux_file)): result = difference_image( ref, ref, params, stamp_positions=stamp_positions, psf_image=psf_file, star_positions=star_positions, star_group_boundaries=star_group_boundaries, detector_mean_positions_x=detector_mean_positions_x, detector_mean_positions_y=detector_mean_positions_y, star_sky=star_sky) if isinstance(result.flux, np.ndarray): print 'ungrouping fluxes' result.flux = result.flux[star_unsort_index].copy() result.dflux = result.dflux[star_unsort_index].copy() np.savetxt(ref_flux_file, np.vstack((result.flux, result.dflux)).T) # # Process images # if params.make_difference_images: if not (params.use_GPU) and (params.n_parallel > 1): pool = Pool(params.n_parallel) pool.map( process_image_helper, itertools.izip( files, itertools.repeat( (ref, params, stamp_positions, star_positions, star_group_boundaries, star_unsort_index, detector_mean_positions_x, detector_mean_positions_y)))) else: for f in files: process_image( f, (ref, params, stamp_positions, star_positions, star_group_boundaries, star_unsort_index, detector_mean_positions_x, detector_mean_positions_y)) return files
def make_diff_images(filenamelist, refim, params): """ make a diff image for each file in filenamelist: file - refim. filenamelist : list of filenames for 'target' images refim : reference image, either a filename or a DIA Observation object params : DIA parameters object """ star_group_boundaries = None detector_mean_positions_x = None detector_mean_positions_y = None star_unsort_index = None star_positions = None stamp_positions = None sky = 0.0 if isinstance(refim, str) and os.path.exists(refim): refim = DS.Observation(refim, params) # TODO: investigate what is really being done here: # Apply saturation mask and boxcar blurring to reference image mask, _ = IO.read_fits_file( params.loc_output + os.path.sep + 'mask_' + refim.name) refim.mask = mask pm = params.pixel_max params.pixel_max *= 0.9 refim.mask *= IM.compute_saturated_pixel_mask(refim.image, 4, params) params.pixel_max = pm refim.blur = IM.boxcar_blur(refim.image) if params.mask_cluster: refim.mask *= IM.mask_cluster(refim.image, refim.mask, params) # For each given filename, get a pyDIA observation object image_list = get_observation_list(filenamelist, params) # Register the images, using the ref image as the registration template, # unless the user has specified otherwise if not params.registration_image: params.registration_image = refim.fullname registered_image_list = register_images(image_list, params) # make diff images: im - ref for im in registered_image_list: result = DIA.difference_image( refim, im, params, stamp_positions=stamp_positions, psf_image=params.loc_output + os.path.sep + 'psf.fits', star_positions=star_positions, star_group_boundaries=star_group_boundaries, detector_mean_positions_x=detector_mean_positions_x, detector_mean_positions_y=detector_mean_positions_y) del im.image del im.mask del im.inv_variance hdr = fits.getheader(im.fullname) # TODO : use astropy fits to propagate header with WCS from parent image # Save output images to files if isinstance(result.diff, np.ndarray): IO.write_image(result.diff, params.loc_output + os.path.sep + 'd_' + im.name, header=hdr)