def reference(self): """ This function ... :return: """ # Inform the user log.info("Estimating background with photutils ...") # Plot total mask if self.config.plot: plotting.plot_mask(self.total_mask, title="total mask") integer_aperture_radius = int(math.ceil(self.aperture_radius)) box_shape = (integer_aperture_radius, integer_aperture_radius) filter_size = (3, 3) # Estimate the background sigma_clip = SigmaClip(sigma=3., iters=10) #bkg_estimator = MedianBackground() bkg_estimator = SExtractorBackground() bkg = Background2D(self.frame.data, box_shape, filter_size=filter_size, sigma_clip=sigma_clip, bkg_estimator=bkg_estimator, mask=self.total_mask.data) # Statistics #print("median background", bkg.background_median) #print("rms background", bkg.background_rms_median) self.statistics.reference = Map() self.statistics.reference.median = bkg.background_median self.statistics.reference.rms = bkg.background_rms_median # Plot if self.config.plot: plotting.plot_box(bkg.background, title="background from photutils") # Set the sky self.reference_sky = Frame(bkg.background) # Set bkg object self.photutils_bkg = bkg # Plot if self.config.plot: plotting.plot_box(self.reference_sky, title="reference sky")
def load_i1(self): """ This function ... :return: """ # Inform the user log.info("Loading the IRAC 3.6 micron image ...") # Determine the path to the truncated 3.6 micron image #path = fs.join(truncation_path, "IRAC I1.fits") path = fs.join(self.prep_path, "IRAC I1", "result.fits") frame = Frame.from_file(path) # Convert the frame to Jy/pix conversion_factor = 1.0 conversion_factor *= 1e6 # Convert the 3.6 micron image from Jy / sr to Jy / pixel pixelscale = frame.average_pixelscale pixel_factor = (1.0/pixelscale**2).to("pix2/sr").value conversion_factor /= pixel_factor frame *= conversion_factor frame.unit = "Jy" # Set the frame self.i1_jy = frame
def make_sources(self): """ This function ... :return: """ # Inform the user log.info("Making the sources ...") flux_range = [self.config.flux_range.min, self.config.flux_range.max] xmean_range = [0, self.config.shape[1]] ymean_range = [0, self.config.shape[0]] # Ranges of sigma xstddev_range = [self.sources_sigma, self.sources_sigma] ystddev_range = [self.sources_sigma, self.sources_sigma] table = make_random_gaussians(self.config.nsources, flux_range, xmean_range, ymean_range, xstddev_range, ystddev_range, random_state=12345) self.source_table = table data = make_gaussian_sources(self.config.shape, table) self.sources = Frame(data) # mask self.sources[self.rotation_mask] = 0.0 if self.config.plot: plotting.plot_box(self.sources, title="sources")
def get_frames(self): """ This function ... :return: """ # Inform theb user log.info("Getting the frames ...") # Get the frames #self.frames = self.database.get_framelist_for_filters(self.galaxy_name, filter_names) self.frames = FrameList() # Loop over the filter names for filter_name in filter_names: # Parse filter fltr = parse_filter(filter_name) # Get wcs wcs = get_coordinate_system(fltr) # Generate frame #frame = Frame.random(wcs.shape, wcs=wcs, filter=fltr) frame = Frame.ones(wcs.shape, wcs=wcs, filter=fltr) frame.unit = "Jy" # Add the frame self.frames.append(frame)
def get_frames(self): """ This function ... :return: """ # Inform theb user log.info("Getting the frames ...") # Get the frames #self.frames = self.database.get_framelist_for_filters(self.galaxy_name, filter_names) self.frames = FrameList() # Loop over the filter names for filter_name in filter_names: # Parse filter fltr = parse_filter(filter_name) # Get wcs wcs = get_coordinate_system(fltr) # Generate frame #frame = Frame.random(wcs.shape, wcs=wcs, filter=fltr) frame = Frame.ones(wcs.shape, wcs=wcs, filter=fltr) frame.unit = "Jy" # Add the frame self.frames.append(frame)
def load_i1(self): """ This function ... :return: """ # Inform the user log.info("Loading the IRAC 3.6 micron image ...") # Determine the path to the truncated 3.6 micron image #path = fs.join(truncation_path, "IRAC I1.fits") path = fs.join(self.prep_path, "IRAC I1", "result.fits") frame = Frame.from_file(path) # Convert the frame to Jy/pix conversion_factor = 1.0 conversion_factor *= 1e6 # Convert the 3.6 micron image from Jy / sr to Jy / pixel pixelscale = frame.average_pixelscale pixel_factor = (1.0 / pixelscale**2).to("pix2/sr").value conversion_factor /= pixel_factor frame *= conversion_factor frame.unit = "Jy" # Set the frame self.i1_jy = frame
def initialize_frames(self): """ This function ... :return: """ # Inform the user log.info("Initializing the frames ...") # Loop over the filters for fltr in self.coordinate_systems.filters: # Debugging log.debug("Initializing the '" + str(fltr) + "' frame ...") # Get the wcs wcs = self.coordinate_systems[fltr] # Create new frame frame = Frame.zeros(wcs.shape) # Add the wcs frame.wcs = wcs # Set the filter frame.filter = fltr # Set the unit frame.unit = "Jy" # Add the frame self.frames[fltr] = frame
def get_map(self, name): """ This function ... :param name: :return: """ # Determine path path = fs.join(self.maps_path, name) return Frame.from_file(path)
def make_galaxy(self): """ This function ... :return: """ # Inform the user log.info("Adding smooth galaxy source ...") effective_radius = self.config.galaxy_effective_radius effective_galaxy_angle = self.config.galaxy_angle + self.effective_rotation_angle axial_ratio = self.config.galaxy_axial_ratio angle_deg = effective_galaxy_angle.to("deg").value # Produce guess values initial_sersic_amplitude = self.config.galaxy_central_flux initial_sersic_r_eff = effective_radius initial_sersic_n = self.config.galaxy_sersic_index initial_sersic_x_0 = self.config.galaxy_position.x initial_sersic_y_0 = self.config.galaxy_position.y initial_sersic_ellip = (axial_ratio - 1.0) / axial_ratio initial_sersic_theta = np.deg2rad(angle_deg) # Produce sersic model from guess parameters, for time trials sersic_x, sersic_y = np.meshgrid(np.arange(self.xsize), np.arange(self.ysize)) sersic_model = Sersic2D(amplitude=initial_sersic_amplitude, r_eff=initial_sersic_r_eff, n=initial_sersic_n, x_0=initial_sersic_x_0, y_0=initial_sersic_y_0, ellip=initial_sersic_ellip, theta=initial_sersic_theta) sersic_map = sersic_model(sersic_x, sersic_y) # Set the galaxy frame self.galaxy = Frame(sersic_map) # Mask self.galaxy[self.rotation_mask] = 0.0 limit_radius = self.config.galaxy_relative_asymptotic_radius * effective_radius # Create galaxy region galaxy_center = PixelCoordinate(initial_sersic_x_0, initial_sersic_y_0) galaxy_radius = PixelStretch(limit_radius, limit_radius / axial_ratio) self.galaxy_region = PixelEllipseRegion(galaxy_center, galaxy_radius, effective_galaxy_angle) # Set galaxy map zero outside certain radius self.galaxy[self.galaxy_mask.inverse()] = 0.0 # Plot if self.config.plot: plotting.plot_box(self.galaxy, title="galaxy")
def get_map(self, name): """ This function ... :param name: :return: """ # Determine path path = fs.join(self.maps_path, name) return Frame.from_file(path)
def dust_map(self): """ This function ... :return: """ # Dust dust_map = Frame.from_file(dust_map_path) dust_map.wcs = self.wcs return dust_map
def ionizing_stars_map(self): """ This function .... :return: """ # Ionizing stars ionizing_map = Frame.from_file(ionizing_map_path) ionizing_map.wcs = self.wcs return ionizing_map
def old_stars_map(self): """ This function ... :return: """ # Old stars old_map = Frame.from_file(old_map_path) old_map.wcs = self.wcs return old_map
def young_stars_map(self): """ This function ... :return: """ # young stars young_map = Frame.from_file(young_map_path) young_map.wcs = self.wcs return young_map
def load_maps(self): """ This function ... :return: """ # Inform the user log.info("Loading the input maps ...") # Determine path to maps directory maps_path = fs.join(m81_data_path, "maps") # Determine the path to the header file header_path = fs.join(maps_path, "header.txt") header = Header.fromtextfile(header_path) wcs = CoordinateSystem(header=header) # Old stars old_map_path = fs.join(maps_path, old_filename) old_map = Frame.from_file(old_map_path) old_map.wcs = wcs self.maps["old"] = old_map # young stars young_map_path = fs.join(maps_path, young_filename) young_map = Frame.from_file(young_map_path) young_map.wcs = wcs self.maps["young"] = young_map # Ionizing stars ionizing_map_path = fs.join(maps_path, ionizing_filename) ionizing_map = Frame.from_file(ionizing_map_path) ionizing_map.wcs = wcs self.maps["ionizing"] = ionizing_map # Dust dust_map_path = fs.join(maps_path, dust_filename) dust_map = Frame.from_file(dust_map_path) dust_map.wcs = wcs self.maps["dust"] = dust_map
def old_stars_map(self): """ This function ... :return: """ # Old stars old_map = Frame.from_file(old_map_path) old_map.wcs = self.wcs return old_map
def ionizing_stars_map(self): """ This function .... :return: """ # Ionizing stars ionizing_map = Frame.from_file(ionizing_map_path) ionizing_map.wcs = self.wcs return ionizing_map
def load_model(self): """ This function ... :return: """ # Inform the user log.info("Loading the model image ...") # Determine the path to the truncated model image path = fs.join(self.components_images_path, "model.fits") self.model_jy = Frame.from_file(path)
def load_disk(self): """ This function ... :return: """ # Inform the user log.info("Loading the disk image ...") # Determine the path to the disk image path = fs.join(self.components_images_path, "disk.fits") self.disk_jy = Frame.from_file(path)
def load_bulge2d(self): """ This function ... :return: """ # Inform the user log.info("Loading the bulge 2D image ...") # Determine the path to the bulge 2D image path = fs.join(self.components_images_path, "bulge2D.fits") self.bulge2d_jy = Frame.from_file(path)
def dust_map(self): """ This function ... :return: """ # Dust dust_map = Frame.from_file(dust_map_path) dust_map.wcs = self.wcs return dust_map
def young_stars_map(self): """ This function ... :return: """ # young stars young_map = Frame.from_file(young_map_path) young_map.wcs = self.wcs return young_map
def load_images(self): """ This function ... :return: """ # Inform the user log.info("Loading the images ...") # The common wcs of the images wcs = None # Loop over the images in the data directory for path, filename in fs.files_in_path(self.data_path, extension="fits", returns=["path", "name"]): # Load the frame frame = Frame.from_file(path) # Set filter previous_filter = frame.filter frame.filter = parse_filter(filename.split("_norm")[0]) if previous_filter != frame.filter: frame.save() # Check filter if str(frame.filter) not in [ str(fltr) for fltr in self.config.fitting_filters ]: continue # Determine name name = str(frame.filter) # Check wcs if wcs is None: wcs = frame.wcs elif wcs == frame.wcs: pass else: raise IOError("The coordinate system of image '" + filename + "' does not match that of other images") # Debugging log.debug("Adding frame '" + filename + "' ...") # Add to dictionary self.images[name] = frame # Set original path self.image_paths[name] = path # Set the wcs self.wcs = wcs
def load_bulge2d(self): """ This function ... :return: """ # Inform the user log.info("Loading the bulge 2D image ...") # Determine the path to the bulge 2D image path = fs.join(self.components_images_path, "bulge2D.fits") self.bulge2d_jy = Frame.from_file(path)
def load_model(self): """ This function ... :return: """ # Inform the user log.info("Loading the model image ...") # Determine the path to the truncated model image path = fs.join(self.components_images_path, "model.fits") self.model_jy = Frame.from_file(path)
def load_disk(self): """ This function ... :return: """ # Inform the user log.info("Loading the disk image ...") # Determine the path to the disk image path = fs.join(self.components_images_path, "disk.fits") self.disk_jy = Frame.from_file(path)
def make_constant_sky(self): """ This function .. :return: """ # Inform the user log.info("Making constant sky ...") self.constant_sky = Frame.filled_like(self.sources, self.config.constant_sky) # Mask self.constant_sky[self.rotation_mask] = 0.0
def make_constant_sky(self): """ This function .. :return: """ # Inform the user log.info("Making constant sky ...") self.constant_sky = Frame.filled_like(self.sources, self.config.constant_sky) # Mask self.constant_sky[self.rotation_mask] = 0.0
def make_random_frame(nxpixels, nypixels=None): """ This function ... :param nxpixels: :param nypixels: :return: """ # Set shape if nypixels is None: nypixels = nxpixels shape = (nypixels, nxpixels) # Return the frame return Frame.random(shape)
def old(self): """ This function ... :return: """ exit() # FWHM of all the images fwhm = 11.18 * u("arcsec") fwhm_pix = (fwhm / frame.average_pixelscale).to("pix").value sigma = fwhm_pix * statistics.fwhm_to_sigma # Get the center pixel of the galaxy parameters_path = fs.join(components_path, "parameters.dat") parameters = load_parameters(parameters_path) center = parameters.center.to_pixel(frame.wcs) # Create a source around the galaxy center ellipse = PixelEllipseRegion(center, 20.0*sigma) source = Source.from_ellipse(model_residual, ellipse, 1.5) source.estimate_background("polynomial") source.plot() position = source.center model = source.subtracted.fit_model(position, "Gaussian") rel_center = center - Extent(source.x_min, source.y_min) rel_model = fitting.shifted_model(model, -source.cutout.x_min, -source.cutout.y_min) plotting.plot_peak_model(source.cutout, rel_center.x, rel_center.y, rel_model) model_fwhm_pix = fitting.fwhm(model) model_fwhm = (model_fwhm_pix * frame.average_pixelscale).to("arcsec") print("Model FWHM: ", model_fwhm) evaluated_model = source.cutout.evaluate_model(model) all_residual = Frame(np.copy(model_residual)) all_residual[source.y_slice, source.x_slice] -= evaluated_model all_residual.saveto(fs.join(residuals_path, "all_residual.fits")) model = Gaussian2D(amplitude=0.0087509425805, x_mean=center.x, y_mean=center.y, x_stddev=sigma, y_stddev=sigma) rel_model = fitting.shifted_model(model, -source.cutout.x_min, -source.cutout.y_min) plotting.plot_peak_model(source.cutout, rel_center.x, rel_center.y, rel_model) evaluated_model = source.cutout.evaluate_model(model) all_residual2 = Frame(np.copy(model_residual)) all_residual2[source.y_slice, source.x_slice] -= evaluated_model all_residual2.saveto(fs.join(residuals_path, "all_residual2.fits"))
def make_rotation_mask(self): """ This function ... :return: """ # Inform the user log.info("Making rotation mask ...") # Rotate if self.config.rotate: frame = Frame.zeros(self.config.shape) self.rotation_mask = frame.rotate(self.config.rotation_angle) else: self.rotation_mask = Mask.empty(self.config.shape[1], self.config.shape[0])
def make_rotation_mask(self): """ This function ... :return: """ # Inform the user log.info("Making rotation mask ...") # Rotate if self.config.rotate: frame = Frame.zeros(self.config.shape) self.rotation_mask = frame.rotate(self.config.rotation_angle) else: self.rotation_mask = Mask.empty(self.config.shape[1], self.config.shape[0])
def reference(self): """ This function ... :return: """ # Inform the user log.info("Estimating background with photutils ...") # Plot total mask if self.config.plot: plotting.plot_mask(self.total_mask, title="total mask") integer_aperture_radius = int(math.ceil(self.aperture_radius)) box_shape = (integer_aperture_radius, integer_aperture_radius) filter_size = (3, 3) # Estimate the background sigma_clip = SigmaClip(sigma=3., iters=10) #bkg_estimator = MedianBackground() bkg_estimator = SExtractorBackground() bkg = Background2D(self.frame.data, box_shape, filter_size=filter_size, sigma_clip=sigma_clip, bkg_estimator=bkg_estimator, mask=self.total_mask.data) # Statistics #print("median background", bkg.background_median) #print("rms background", bkg.background_rms_median) self.statistics.reference = Map() self.statistics.reference.median = bkg.background_median self.statistics.reference.rms = bkg.background_rms_median # Plot if self.config.plot: plotting.plot_box(bkg.background, title="background from photutils") # Set the sky self.reference_sky = Frame(bkg.background) # Set bkg object self.photutils_bkg = bkg # Plot if self.config.plot: plotting.plot_box(self.reference_sky, title="reference sky")
def make_gradient_sky(self): """ This function ... :return: """ # Inform the user log.info("Making gradient sky ...") y, x = np.mgrid[:self.ysize, :self.xsize] # Create gradient sky self.gradient_sky = Frame(x * y / 5000.) # Mask padded self.gradient_sky[self.rotation_mask] = 0.0 # Plot #if self.config.plot: plotting.plot_difference(self.frame, self.real_sky, title="frame with background") if self.config.plot: plotting.plot_box(self.gradient_sky, title="gradient sky")
def make_noise(self): """ This function ... :return: """ # Inform the user log.info("Making noise map ...") # Make noise data = make_noise_image(self.config.shape, type='gaussian', mean=0., stddev=self.config.noise_stddev, random_state=12345) self.noise = Frame(data) # Mask self.noise[self.rotation_mask] = 0.0 # Plot #if self.config.plot: plotting.plot_difference(self.frame, self.real_sky, title="original") if self.config.plot: plotting.plot_box(self.noise, title="noise")
log.start("Starting decomposition_residuals ...") # ----------------------------------------------------------------- components_path = fs.join(config.path, "components") truncation_path = fs.join(config.path, "truncated") residuals_path = fs.join(config.path, "residuals") # ----------------------------------------------------------------- # Inform the user log.info("Loading the IRAC 3.6 micron image ...") # Determine the path to the truncated 3.6 micron image path = fs.join(truncation_path, "IRAC I1.fits") frame = Frame.from_file(path) # Convert the frame to Jy/pix conversion_factor = 1.0 conversion_factor *= 1e6 # Convert the 3.6 micron image from Jy / sr to Jy / pixel pixelscale = frame.average_pixelscale pixel_factor = (1.0/pixelscale**2).to("pix2/sr").value conversion_factor /= pixel_factor frame *= conversion_factor frame.unit = "Jy" frame.save(fs.join(residuals_path, "i1_jy.fits")) # Inform the user
# ----------------------------------------------------------------- # Save the animation if animation is not None: path = fs.join(output_path, "animation.gif") animation.save(path) # ----------------------------------------------------------------- # Inform the user log.info("Writing the result ...") # Determine the path to the result result_path = fs.join(output_path, image.name + ".fits") # Save the resulting image as a FITS file image.frames.primary.save(result_path, header=image.original_header) # ----------------------------------------------------------------- # Inform the user log.info("Writing the mask ...") # Determine the path to the mask mask_path = fs.join(output_path, "mask.fits") # Save the total mask as a FITS file Frame(extractor.mask.astype(float)).save(mask_path) # -----------------------------------------------------------------
definition.add_optional("colours", "string", "colour or colour scale", "red") definition.add_optional("alpha", "string", "alpha method", default_alpha_method, suggestions=alpha_methods) definition.add_optional("output", "string", "output filepath", letter="o") definition.add_optional("peak_alpha", "real", "alpha of peak value", 1.) definition.add_optional("max_npixels", "positive_integer", "maximum number of pixels") definition.add_optional("downsample", "positive_real", "downsample with this factor") definition.add_flag("show", "show after creating", False) config = parse_arguments("fits_to_png", definition) # ----------------------------------------------------------------- # Inform the user log.info("Loading the FITS file ...") # Load the FITS file frame = Frame.from_file(config.filename) # ----------------------------------------------------------------- if config.output is not None: filepath = fs.absolute_or_in(config.output, fs.cwd()) else: # Determine the path name = fs.strip_extension(fs.name(config.filename)) filepath = fs.absolute_path(name + ".png") # ----------------------------------------------------------------- # Max npixels if config.max_npixels is not None:
# Create a mask of the pixels that are NaNs nans = Mask.is_nan(frame) # Set the NaN pixels to zero in the frame frame[nans] = 0.0 # Interpolate the frame in the masked pixels if arguments.method == "biharmonic": data = interpolation.inpaint_biharmonic(frame, mask) elif arguments.method == "local_mean": data = interpolation.in_paint(frame, mask, method="localmean") else: raise ValueError( "Invalid interpolation method (should be 'biharmonic' or 'local_mean')" ) new_frame = Frame(data) # Set the original NaN pixels back to NaN new_frame[nans] = float("nan") # Inform the user log.info("Saving the result ...") # Save the result path = fs.join(output_path, arguments.image) new_frame.save(path, header=header) # Write the mask if arguments.mask: path = fs.join(output_path, "mask.fits")
# ----------------------------------------------------------------- names_column = [] paths_column = [] prep_names_column = [] names = ["Image name", "Image path", "Preparation name"] # Loop over all subdirectories of the data directory for path, name in fs.directories_in_path(fs.join(config.path, "data"), not_contains="bad", returns=["path", "name"]): # Loop over all FITS files found in the current subdirectory for image_path, image_name in fs.files_in_path(path, extension="fits", not_contains="_Error", returns=["path", "name"]): # Open the image frame frame = Frame.from_file(image_path) # Determine the preparation name if frame.filter is not None: prep_name = str(frame.filter) else: prep_name = image_name # Set the row entries names_column.append(image_name) paths_column.append(image_path) prep_names_column.append(prep_name) # Create the table data = [names_column, paths_column, prep_names_column] table = tables.new(data, names) # Check whether the preparation directory exists
the_image_path = None # Find the image corresponding to the specified factor for image_path, image_name in fs.files_in_path(lowres_path, extension="fits", returns=["path", "name"]): # Determine the factor factor = real(image_name) # If the factor corresponds to the specified factor, take this image if np.isclose(factor, config.factor, rtol=0.01): the_image_path = image_path break # Check if the_image_path is None: raise ValueError("No truncated " + filter_name + " image found for a factor of " + str(config.factor)) # Add the image frame = Frame.from_file(the_image_path) plotter.add_image(frame, filter_name) # ----------------------------------------------------------------- # Run the plotter plotter.run() # -----------------------------------------------------------------
data_images_path = get_data_images_path(modeling_path) # ----------------------------------------------------------------- shapes = dict() # Loop over the images for image_path, image_name in fs.files_in_path(data_images_path, extension="fits", not_contains="poisson", returns=["path", "name"], recursive=True, recursion_level=1): # Load the image frame = Frame.from_file(image_path, silent=True) # Determine filter name filter_name = frame.filter_name # Set pixel shape shapes[filter_name] = frame.shape # ----------------------------------------------------------------- # Sort on shape sorted_filter_names = sorted(shapes.keys(), key=lambda name: shapes[name]) # ----------------------------------------------------------------- print("")
class SkyTest(TestImplementation): """ This class ... """ def __init__(self, *args, **kwargs): """ The constructor ... :param kwargs: """ # Call the constructor of the base class super(SkyTest, self).__init__(*args, **kwargs) # FRAME COMPONENTS # The sources map self.sources = None # The noise map self.noise = None # The galaxy self.galaxy = None # Real sky frames self.constant_sky = None self.gradient_sky = None # TABLES self.source_table = None # MASKS # The sources mask self.sources_mask = None # The rotation mask self.rotation_mask = None # The galaxy self.galaxy_region = None # SKY ESTIMATION # Photutils Background2D object self.photutils_bkg = None # Sky reference estimation self.reference_sky = None # Path self.subtraction_path = None # The sky subtractor self.subtractor = None # STATISTICS # The statistics self.statistics = Map() # ----------------------------------------------------------------- def run(self, **kwargs): """ This function ... :param kwargs: :return: """ # 1. Call the setup function self.setup(**kwargs) # 2. Make rotation mask self.make_rotation_mask() # 3. Generate the sources self.make_sources() # 4. Make noise self.make_noise() # 5. Make galaxy self.make_galaxy() # 6. Make sky self.make_sky() # 7. Mask sources self.mask_sources() # 8. Statistics self.calculate_statistics() # 9. Reference self.reference() # 10. Subtract self.subtract() # 11. Write self.write() # 12. Plot self.plot() # ----------------------------------------------------------------- def setup(self, **kwargs): """ This function ... :param kwargs: :return: """ # Call the setup function of the base class super(SkyTest, self).setup(**kwargs) # Set the subtraction path self.subtraction_path = fs.create_directory_in(self.path, "subtraction") # ----------------------------------------------------------------- def make_rotation_mask(self): """ This function ... :return: """ # Inform the user log.info("Making rotation mask ...") # Rotate if self.config.rotate: frame = Frame.zeros(self.config.shape) self.rotation_mask = frame.rotate(self.config.rotation_angle) else: self.rotation_mask = Mask.empty(self.config.shape[1], self.config.shape[0]) # ----------------------------------------------------------------- @property def effective_rotation_angle(self): """ THis function ... :return: """ if self.config.rotate: return self.config.rotation_angle else: return Angle(0.0, "deg") # ----------------------------------------------------------------- @property def shape(self): """ THis function ... :return: """ return self.rotation_mask.shape # ----------------------------------------------------------------- @property def xsize(self): """ This function ... :return: """ return self.rotation_mask.xsize # ----------------------------------------------------------------- @property def ysize(self): """ This function ... :return: """ return self.rotation_mask.ysize # ----------------------------------------------------------------- @property def sources_sigma(self): """ This function ... :return: """ return self.config.fwhm * statistics.fwhm_to_sigma # ----------------------------------------------------------------- def make_sources(self): """ This function ... :return: """ # Inform the user log.info("Making the sources ...") flux_range = [self.config.flux_range.min, self.config.flux_range.max] xmean_range = [0, self.config.shape[1]] ymean_range = [0, self.config.shape[0]] # Ranges of sigma xstddev_range = [self.sources_sigma, self.sources_sigma] ystddev_range = [self.sources_sigma, self.sources_sigma] table = make_random_gaussians(self.config.nsources, flux_range, xmean_range, ymean_range, xstddev_range, ystddev_range, random_state=12345) self.source_table = table data = make_gaussian_sources(self.config.shape, table) self.sources = Frame(data) # mask self.sources[self.rotation_mask] = 0.0 if self.config.plot: plotting.plot_box(self.sources, title="sources") # ----------------------------------------------------------------- def make_noise(self): """ This function ... :return: """ # Inform the user log.info("Making noise map ...") # Make noise data = make_noise_image(self.config.shape, type='gaussian', mean=0., stddev=self.config.noise_stddev, random_state=12345) self.noise = Frame(data) # Mask self.noise[self.rotation_mask] = 0.0 # Plot #if self.config.plot: plotting.plot_difference(self.frame, self.real_sky, title="original") if self.config.plot: plotting.plot_box(self.noise, title="noise") # ----------------------------------------------------------------- def make_galaxy(self): """ This function ... :return: """ # Inform the user log.info("Adding smooth galaxy source ...") effective_radius = self.config.galaxy_effective_radius effective_galaxy_angle = self.config.galaxy_angle + self.effective_rotation_angle axial_ratio = self.config.galaxy_axial_ratio angle_deg = effective_galaxy_angle.to("deg").value # Produce guess values initial_sersic_amplitude = self.config.galaxy_central_flux initial_sersic_r_eff = effective_radius initial_sersic_n = self.config.galaxy_sersic_index initial_sersic_x_0 = self.config.galaxy_position.x initial_sersic_y_0 = self.config.galaxy_position.y initial_sersic_ellip = (axial_ratio - 1.0) / axial_ratio initial_sersic_theta = np.deg2rad(angle_deg) # Produce sersic model from guess parameters, for time trials sersic_x, sersic_y = np.meshgrid(np.arange(self.xsize), np.arange(self.ysize)) sersic_model = Sersic2D(amplitude=initial_sersic_amplitude, r_eff=initial_sersic_r_eff, n=initial_sersic_n, x_0=initial_sersic_x_0, y_0=initial_sersic_y_0, ellip=initial_sersic_ellip, theta=initial_sersic_theta) sersic_map = sersic_model(sersic_x, sersic_y) # Set the galaxy frame self.galaxy = Frame(sersic_map) # Mask self.galaxy[self.rotation_mask] = 0.0 limit_radius = self.config.galaxy_relative_asymptotic_radius * effective_radius # Create galaxy region galaxy_center = PixelCoordinate(initial_sersic_x_0, initial_sersic_y_0) galaxy_radius = PixelStretch(limit_radius, limit_radius / axial_ratio) self.galaxy_region = PixelEllipseRegion(galaxy_center, galaxy_radius, effective_galaxy_angle) # Set galaxy map zero outside certain radius self.galaxy[self.galaxy_mask.inverse()] = 0.0 # Plot if self.config.plot: plotting.plot_box(self.galaxy, title="galaxy") # ----------------------------------------------------------------- def make_sky(self): """ This function ... :return: """ # Inform the user log.info("Making sky ...") # make constant sky self.make_constant_sky() # Make gradient sky self.make_gradient_sky() # ----------------------------------------------------------------- def make_constant_sky(self): """ This function .. :return: """ # Inform the user log.info("Making constant sky ...") self.constant_sky = Frame.filled_like(self.sources, self.config.constant_sky) # Mask self.constant_sky[self.rotation_mask] = 0.0 # Plot # ----------------------------------------------------------------- def make_gradient_sky(self): """ This function ... :return: """ # Inform the user log.info("Making gradient sky ...") y, x = np.mgrid[:self.ysize, :self.xsize] # Create gradient sky self.gradient_sky = Frame(x * y / 5000.) # Mask padded self.gradient_sky[self.rotation_mask] = 0.0 # Plot #if self.config.plot: plotting.plot_difference(self.frame, self.real_sky, title="frame with background") if self.config.plot: plotting.plot_box(self.gradient_sky, title="gradient sky") # ----------------------------------------------------------------- @lazyproperty def sky(self): """ This function ... :return: """ return self.constant_sky + self.gradient_sky # ----------------------------------------------------------------- @lazyproperty def frame(self): """ This fucntion ... :return: """ return self.sources_with_galaxy_and_noise + self.sky # ----------------------------------------------------------------- @lazyproperty def sources_with_noise(self): """ This function ... :return: """ return self.noise + self.sources # ----------------------------------------------------------------- @lazyproperty def sources_with_galaxy_and_noise(self): """ This function ... :return: """ return self.sources_with_noise + self.galaxy # ----------------------------------------------------------------- def mask_sources(self): """ This function ... :return: """ # Inform the user log.info("Masking sources ...") # Create sources mask mask = make_source_mask(self.sources_with_noise.data, snr=2, npixels=5, dilate_size=11, mask=self.rotation_mask) self.sources_mask = Mask(mask) # Plot if self.config.plot: plotting.plot_mask(self.sources_mask, title="sources mask") # ----------------------------------------------------------------- def calculate_statistics(self): """ This function ... :return: """ # Inform the user log.info("Calculating statistics ...") # Calculate statistics no sigma clipping self.calculate_statistics_no_clipping() # Calculate statistics clipping self.calculate_statistics_clipping() # Calculate statistics masked sources self.calculate_statistics_masked() # ----------------------------------------------------------------- def calculate_statistics_no_clipping(self): """ This function ... :return: """ # Compress (remove masked values) flattened = np.ma.array(self.sources_with_noise.data, mask=self.rotation_mask.data).compressed() median = np.median(flattened) biweight_loc = biweight_location(flattened) biweight_midvar = biweight_midvariance(flattened) median_absolute_deviation = mad_std(flattened) #print("median", median) #print("biweigth_loc", biweight_loc) #print("biweight_midvar", biweight_midvar) #print("median_absolute_deviation", median_absolute_deviation) self.statistics.no_clipping = Map() self.statistics.no_clipping.median = median self.statistics.no_clipping.biweight_loc = biweight_loc self.statistics.no_clipping.biweight_midvar = biweight_midvar self.statistics.no_clipping.median_absolute_deviation = median_absolute_deviation # SAME RESULTS: # median = np.median(self.original_frame) # biweight_loc = biweight_location(self.original_frame) # biweight_midvar = biweight_midvariance(self.original_frame) # median_absolute_deviation = mad_std(self.original_frame) # print("median", median) # print("biweigth_loc", biweight_loc) # print("biweight_midvar", biweight_midvar) # print("median_absolute_deviation", median_absolute_deviation) # ----------------------------------------------------------------- def calculate_statistics_clipping(self): """ This function ... :return: """ # Inform the user log.info("Sigma-clipping ...") # Sigma clip mean, median, std = sigma_clipped_stats(self.sources_with_noise.data, sigma=3.0, iters=5, mask=self.rotation_mask) #print("sigma-clip mean:", mean) #print("sigma-clip median:", median) #print("sigma-clip std:", std) self.statistics.clipping = Map() self.statistics.clipping.mean = mean self.statistics.clipping.median = median self.statistics.clipping.std = std # ----------------------------------------------------------------- def calculate_statistics_masked(self): """ This function ... :return: """ # Inform the user log.info("Calculating statistics with sources masked ...") # Statistics mean, median, std = sigma_clipped_stats(self.sources_with_noise.data, sigma=3.0, mask=self.total_mask.data, iters=5) #print("sigma-clip mean after source masking:", mean) #print("sigma-clip median after source masking:", median) #print("sigma_clip std after source masking:", std) # Set the statistics self.statistics.masked = Map() self.statistics.masked.mean = mean self.statistics.masked.median = median self.statistics.masked.std = std # ----------------------------------------------------------------- @lazyproperty def total_mask(self): """ This function ... :return: """ return self.sources_and_rotation_mask + self.galaxy_mask # ----------------------------------------------------------------- @lazyproperty def sources_and_rotation_mask(self): """ This function ... :return: """ return self.sources_mask + self.rotation_mask # ----------------------------------------------------------------- @lazyproperty def galaxy_mask(self): """ This function ... :return: """ # Make mask return self.galaxy_region.to_mask(self.xsize, self.ysize) # ----------------------------------------------------------------- @lazyproperty def reference_subtracted(self): """ This function ... :return: """ return self.frame - self.reference_sky # ----------------------------------------------------------------- @lazyproperty def subtracted(self): """ This function ... :return: """ return self.frame - self.estimated_sky # ----------------------------------------------------------------- @property def aperture_radius(self): """ This function ... :return: """ return self.config.fwhm * self.config.aperture_fwhm_factor # ----------------------------------------------------------------- @property def aperture_diameter(self): """ This function ... :return: """ return 2.0 * self.aperture_radius # ----------------------------------------------------------------- def reference(self): """ This function ... :return: """ # Inform the user log.info("Estimating background with photutils ...") # Plot total mask if self.config.plot: plotting.plot_mask(self.total_mask, title="total mask") integer_aperture_radius = int(math.ceil(self.aperture_radius)) box_shape = (integer_aperture_radius, integer_aperture_radius) filter_size = (3, 3) # Estimate the background sigma_clip = SigmaClip(sigma=3., iters=10) #bkg_estimator = MedianBackground() bkg_estimator = SExtractorBackground() bkg = Background2D(self.frame.data, box_shape, filter_size=filter_size, sigma_clip=sigma_clip, bkg_estimator=bkg_estimator, mask=self.total_mask.data) # Statistics #print("median background", bkg.background_median) #print("rms background", bkg.background_rms_median) self.statistics.reference = Map() self.statistics.reference.median = bkg.background_median self.statistics.reference.rms = bkg.background_rms_median # Plot if self.config.plot: plotting.plot_box(bkg.background, title="background from photutils") # Set the sky self.reference_sky = Frame(bkg.background) # Set bkg object self.photutils_bkg = bkg # Plot if self.config.plot: plotting.plot_box(self.reference_sky, title="reference sky") # ----------------------------------------------------------------- def subtract(self): """ This function ... :return: """ # Inform the user log.info("Subtracting the sky ...") # Settings settings = dict() settings["estimation"] = dict() settings["estimation"]["method"] = "photutils" settings["estimation"]["aperture_radius"] = self.aperture_radius settings["write"] = True #settings["estimation"]["finishing_step"] = "polynomial" #settings["estimation"]["polynomial_degree"] = self.config.polynomial_degree #settings["estimation"]["fill_method"] = "cubic" settings["plot"] = True # Input input_dict = dict() # Set input input_dict["frame"] = self.frame input_dict["principal_shape"] = self.galaxy_region input_dict["sources_mask"] = self.sources_mask input_dict["extra_mask"] = self.rotation_mask # Create command command = Command( "subtract_sky", "subtract the sky from an artificially created image", settings, input_dict, cwd=self.subtraction_path) # Run the subtraction self.subtractor = self.run_command(command) # ----------------------------------------------------------------- @property def estimated_sky(self): """ This function ... :return: """ return self.subtractor.sky_frame # ----------------------------------------------------------------- @lazyproperty def subtracted(self): """ This function ... :return: """ return self.frame - self.estimated_sky # ----------------------------------------------------------------- @lazyproperty def sky_residual(self): """ This function ... :return: """ return self.estimated_sky - self.sky # ----------------------------------------------------------------- def write(self): """ This function ... :return: """ # Inform the user log.info("Writing ...") # Write the sources with noise self.write_sources() # Write the frame self.write_frame() # Write real sky map self.write_real_sky() # Write sources mask self.write_sources_mask() # Write galaxy mask self.write_galaxy_mask() # Write reference sky self.write_reference_sky() # Write estiamted sky self.write_estimated_sky() # Write residuals self.write_residual() # Write the statistics self.write_statistics() # ----------------------------------------------------------------- def write_sources(self): """ THis function ... :return: """ # Inform the user log.info("Writing the sources frame with noise ...") # Determine the path path = fs.join(self.path, "sources_noise.fits") # Save the frame self.sources_with_noise.saveto(path) # ----------------------------------------------------------------- def write_frame(self): """ This function ... :return: """ # Inform the user log.info("Writing the frame ...") # Determine the path path = fs.join(self.path, "frame.fits") # SAve the frame self.frame.saveto(path) # ----------------------------------------------------------------- def write_real_sky(self): """ This function ... :return: """ # Inform the user log.info("Writing the real sky map ...") # Determine the path path = fs.join(self.path, "real_sky.fits") # Save the map self.sky.saveto(path) # ----------------------------------------------------------------- def write_sources_mask(self): """ This function ... :return: """ # Inform the user log.info("Writing the sources mask ...") # Determine the path path = fs.join(self.path, "sources_mask.fits") # Save self.sources_mask.saveto(path) # ----------------------------------------------------------------- def write_galaxy_mask(self): """ This function ... :return: """ # Inform the user log.info("Writing the galaxy mask ...") # Determine the path path = fs.join(self.path, "galaxy_mask.fits") # Save self.galaxy_mask.saveto(path) # ----------------------------------------------------------------- def write_reference_sky(self): """ This function ... :return: """ # Inform the user log.info("Writing the reference sky map ...") # Determine the path path = fs.join(self.path, "reference_sky.fits") # Save self.reference_sky.saveto(path) # ----------------------------------------------------------------- def write_estimated_sky(self): """ This function ... :return: """ # Inform the user log.info("Writing the estimated sky map ...") # Determine the path path = fs.join(self.path, "estimated_sky.fits") # Save self.estimated_sky.saveto(path) # ----------------------------------------------------------------- def write_subtracted(self): """ This function ... :return: """ # Inform the user log.info("Writing the sky-subtracted frame ...") # Determine the path path = fs.join(self.path, "subtracted.fits") # Save self.subtracted.saveto(path) # ----------------------------------------------------------------- def write_residual(self): """ This function ... :return: """ # Inform the user log.info("Writing the residual map ...") # Determine the path path = fs.join(self.path, "residual.fits") # Save self.sky_residual.saveto(path) # ----------------------------------------------------------------- def write_statistics(self): """ This function ... :return: """ # Inform the user log.info("Writing the statistics ...") # Determine the path path = fs.join(self.path, "statistics.dat") # Write save_mapping(path, self.statistics) # ----------------------------------------------------------------- def plot(self): """ This function ... :return: """ # Inofmrthe user log.info("Plotting ...") # Plot meshes if self.config.plotting.meshes: self.plot_meshes() # ----------------------------------------------------------------- def plot_meshes(self): """ This function ... :return: """ # Inform the user log.info("Plotting the meshes ...") # Plot meshes plt.figure() norm = ImageNormalize(stretch=SqrtStretch()) plt.imshow(self.frame, origin='lower', cmap='Greys_r', norm=norm) self.photutils_bkg.plot_meshes(outlines=True, color='#1f77b4') plt.show()
def test_residual(nframes=5, ngrids=2, max_nrows=3, add_small=False, small_size=6, small_where="last", share_scale=True, scale_reference=None, share_scale_residuals=False, scale_residuals_reference=None, shape=None, adjust_grid=None, relative=True, absolute=False, distributions=False): """ This function ... :param nframes: :param ngrids: :param max_nrows: :param add_small: :param small_size: :param small_where: :param share_scale: :param scale_reference: :param share_scale_residuals: :param scale_residuals_reference: :param shape: :param adjust_grid: :param relative: :param absolute: :param distributions: :return: """ # Same shape if shape is not None: frames = make_random_frames(nframes, xsize=shape[1], ysize=shape[0]) # Get frames elif add_small: if small_where == "last": frames = make_random_frames(nframes-1) small_frame = make_random_frame(small_size) frames.append(small_frame) elif small_where == "first": small_frame = make_random_frame(small_size) frames = [small_frame] frames.extend(make_random_frames(nframes-1)) else: raise ValueError("Invalid option for 'small_where'") # Make all random frames else: frames = make_random_frames(nframes) # Initialize the plotter plotter = ResidualImageGridPlotter() plotter.config.distributions = distributions plotter.config.max_nrows = max_nrows plotter.config.ngrids = ngrids # Set scale references plotter.config.share_scale = share_scale plotter.config.scale_reference = scale_reference plotter.config.share_scale_residuals = share_scale_residuals plotter.config.scale_residuals_reference = scale_residuals_reference plotter.config.adjust_grid = adjust_grid plotter.config.relative = relative plotter.config.absolute = absolute # Loop over the frames for index, frame in enumerate(frames): name = str(index) # Show the shape of the image #print(name, frame.xsize, frame.ysize) # Make observation and model frame observation = frame model = frame + Frame.random_normal(frame.shape, mean=0.0, sigma=0.5) # Add row plotter.add_row(observation, model, name, with_residuals=True) # Run the plotter plotter.run()
mask = region.to_mask(frame.xsize, frame.ysize) # Inform the user log.info("Interpolating the frame within the masked pixels ...") # Create a mask of the pixels that are NaNs nans = Mask.is_nan(frame) # Set the NaN pixels to zero in the frame frame[nans] = 0.0 # Interpolate the frame in the masked pixels if arguments.method == "biharmonic": data = interpolation.inpaint_biharmonic(frame, mask) elif arguments.method == "local_mean": data = interpolation.in_paint(frame, mask, method="localmean") else: raise ValueError("Invalid interpolation method (should be 'biharmonic' or 'local_mean')") new_frame = Frame(data) # Set the original NaN pixels back to NaN new_frame[nans] = float("nan") # Inform the user log.info("Saving the result ...") # Save the result path = fs.join(output_path, arguments.image) new_frame.save(path, header=header) # Write the mask if arguments.mask: path = fs.join(output_path, "mask.fits")
# Create the command-line parser parser = argparse.ArgumentParser() parser.add_argument("region", type=str, help="the name of the region file") parser.add_argument("image", type=str, help="the name of the image file") parser.add_argument("value", type=float, nargs='?', help="the fill value", default='nan') parser.add_argument("--data", action="store_true", help="use the original data for pixels that are not masked") parser.add_argument('--invert', action="store_true", help="invert the mask so that mask covers outside regions") # Parse the command line arguments arguments = parser.parse_args() # ----------------------------------------------------------------- # Load the image frame = Frame.from_file(arguments.image) # Load the region region_name = os.path.splitext(os.path.basename(arguments.region))[0] region = load_as_pixel_region_list(arguments.region, frame.wcs) # Create the mask mask = region.to_mask(x_size=frame.xsize, y_size=frame.ysize) # Calculate the inverse, if requested if arguments.invert: mask = mask.inverse() # ----------------------------------------------------------------- if arguments.data:
name = fs.strip_extension(fs.name(filepath)) # Get header header = get_header(filepath) # Get the filter fltr = get_filter(name, header=header) # Check whether the filter is in the list of filters to be plotted if fltr not in config.filters: continue # Get the index for this filter index = config.filters.index(fltr) # Load the image frame = Frame.from_file(filepath) # Replace zeroes and negatives frame.replace_zeroes_by_nans() frame.replace_negatives_by_nans() # Set the image mock_images[index] = frame # ------------------------------------------------------------------------------ # Get the observed images observed_images = [] for fltr in config.filters: # Check
def old(self): """ This function ... :return: """ exit() # FWHM of all the images fwhm = 11.18 * u("arcsec") fwhm_pix = (fwhm / frame.average_pixelscale).to("pix").value sigma = fwhm_pix * statistics.fwhm_to_sigma # Get the center pixel of the galaxy parameters_path = fs.join(components_path, "parameters.dat") parameters = load_parameters(parameters_path) center = parameters.center.to_pixel(frame.wcs) # Create a source around the galaxy center ellipse = PixelEllipseRegion(center, 20.0 * sigma) source = Source.from_ellipse(model_residual, ellipse, 1.5) source.estimate_background("polynomial") source.plot() position = source.center model = source.subtracted.fit_model(position, "Gaussian") rel_center = center - Extent(source.x_min, source.y_min) rel_model = fitting.shifted_model(model, -source.cutout.x_min, -source.cutout.y_min) plotting.plot_peak_model(source.cutout, rel_center.x, rel_center.y, rel_model) model_fwhm_pix = fitting.fwhm(model) model_fwhm = (model_fwhm_pix * frame.average_pixelscale).to("arcsec") print("Model FWHM: ", model_fwhm) evaluated_model = source.cutout.evaluate_model(model) all_residual = Frame(np.copy(model_residual)) all_residual[source.y_slice, source.x_slice] -= evaluated_model all_residual.saveto(fs.join(residuals_path, "all_residual.fits")) model = Gaussian2D(amplitude=0.0087509425805, x_mean=center.x, y_mean=center.y, x_stddev=sigma, y_stddev=sigma) rel_model = fitting.shifted_model(model, -source.cutout.x_min, -source.cutout.y_min) plotting.plot_peak_model(source.cutout, rel_center.x, rel_center.y, rel_model) evaluated_model = source.cutout.evaluate_model(model) all_residual2 = Frame(np.copy(model_residual)) all_residual2[source.y_slice, source.x_slice] -= evaluated_model all_residual2.saveto(fs.join(residuals_path, "all_residual2.fits"))
parser.add_argument("image", type=str, help="the name of the image file for which to create the region") parser.add_argument("fwhm", type=float, help="the FWHM of the stars (in pixels)") parser.add_argument("sigma_level", type=float, nargs='?', help="the sigma level", default=3.0) parser.add_argument("--color", type=str, help="the color", default="blue") # Parse the command line arguments arguments = parser.parse_args() # ----------------------------------------------------------------- # Load the catalog catalog_name = os.path.splitext(os.path.basename(arguments.catalog))[0] catalog = tables.from_file(arguments.catalog) # Open the frame frame = Frame.from_file(arguments.image) # ----------------------------------------------------------------- # Determine the path to the region file path = os.path.join(os.getcwd(), catalog_name + ".reg") # Create a file f = open(path, 'w') # Initialize the region string print("# Region file format: DS9 version 4.1", file=f) # Create the list of stars for i in range(len(catalog)):
fltr = parse_filter(name) filter_name = str(fltr) # Initializ variable the_image_path = None # Find the image corresponding to the specified factor for image_path, image_name in fs.files_in_path(lowres_path, extension="fits", returns=["path", "name"]): # Determine the factor factor = real(image_name) # If the factor corresponds to the specified factor, take this image if np.isclose(factor, config.factor, rtol=0.01): the_image_path = image_path break # Check if the_image_path is None: raise ValueError("No truncated " + filter_name + " image found for a factor of " + str(config.factor)) # Add the image frame = Frame.from_file(the_image_path) plotter.add_image(frame, filter_name) # ----------------------------------------------------------------- # Run the plotter plotter.run() # -----------------------------------------------------------------
default='nan') parser.add_argument( "--data", action="store_true", help="use the original data for pixels that are not masked") parser.add_argument('--invert', action="store_true", help="invert the mask so that mask covers outside regions") # Parse the command line arguments arguments = parser.parse_args() # ----------------------------------------------------------------- # Load the image frame = Frame.from_file(arguments.image) # Load the region region_name = os.path.splitext(os.path.basename(arguments.region))[0] region = Region.from_file(arguments.region) # Create the mask mask = Mask(region.get_mask(shape=frame.shape)) # Calculate the inverse, if requested if arguments.invert: mask = mask.inverse() # ----------------------------------------------------------------- if arguments.data:
nargs='?', help="the sigma level", default=3.0) parser.add_argument("--color", type=str, help="the color", default="blue") # Parse the command line arguments arguments = parser.parse_args() # ----------------------------------------------------------------- # Load the catalog catalog_name = os.path.splitext(os.path.basename(arguments.catalog))[0] catalog = tables.from_file(arguments.catalog) # Open the frame frame = Frame.from_file(arguments.image) # ----------------------------------------------------------------- # Determine the path to the region file path = os.path.join(os.getcwd(), catalog_name + ".reg") # Create a file f = open(path, 'w') # Initialize the region string print("# Region file format: DS9 version 4.1", file=f) # Create the list of stars for i in range(len(catalog)):
class SkyTest(TestImplementation): """ This class ... """ def __init__(self, *args, **kwargs): """ The constructor ... :param kwargs: """ # Call the constructor of the base class super(SkyTest, self).__init__(*args, **kwargs) # FRAME COMPONENTS # The sources map self.sources = None # The noise map self.noise = None # The galaxy self.galaxy = None # Real sky frames self.constant_sky = None self.gradient_sky = None # TABLES self.source_table = None # MASKS # The sources mask self.sources_mask = None # The rotation mask self.rotation_mask = None # The galaxy self.galaxy_region = None # SKY ESTIMATION # Photutils Background2D object self.photutils_bkg = None # Sky reference estimation self.reference_sky = None # Path self.subtraction_path = None # The sky subtractor self.subtractor = None # STATISTICS # The statistics self.statistics = Map() # ----------------------------------------------------------------- def _run(self, **kwargs): """ This function ... :param kwargs: :return: """ # 2. Make rotation mask self.make_rotation_mask() # 3. Generate the sources self.make_sources() # 4. Make noise self.make_noise() # 5. Make galaxy self.make_galaxy() # 6. Make sky self.make_sky() # 7. Mask sources self.mask_sources() # 8. Statistics self.calculate_statistics() # 9. Reference self.reference() # 10. Subtract self.subtract() # 11. Write self.write() # 12. Plot self.plot() # ----------------------------------------------------------------- def setup(self, **kwargs): """ This function ... :param kwargs: :return: """ # Call the setup function of the base class super(SkyTest, self).setup(**kwargs) # Set the subtraction path self.subtraction_path = fs.create_directory_in(self.path, "subtraction") # ----------------------------------------------------------------- def make_rotation_mask(self): """ This function ... :return: """ # Inform the user log.info("Making rotation mask ...") # Rotate if self.config.rotate: frame = Frame.zeros(self.config.shape) self.rotation_mask = frame.rotate(self.config.rotation_angle) else: self.rotation_mask = Mask.empty(self.config.shape[1], self.config.shape[0]) # ----------------------------------------------------------------- @property def effective_rotation_angle(self): """ THis function ... :return: """ if self.config.rotate: return self.config.rotation_angle else: return Angle(0.0, "deg") # ----------------------------------------------------------------- @property def shape(self): """ THis function ... :return: """ return self.rotation_mask.shape # ----------------------------------------------------------------- @property def xsize(self): """ This function ... :return: """ return self.rotation_mask.xsize # ----------------------------------------------------------------- @property def ysize(self): """ This function ... :return: """ return self.rotation_mask.ysize # ----------------------------------------------------------------- @property def sources_sigma(self): """ This function ... :return: """ return self.config.fwhm * statistics.fwhm_to_sigma # ----------------------------------------------------------------- def make_sources(self): """ This function ... :return: """ # Inform the user log.info("Making the sources ...") flux_range = [self.config.flux_range.min, self.config.flux_range.max] xmean_range = [0, self.config.shape[1]] ymean_range = [0, self.config.shape[0]] # Ranges of sigma xstddev_range = [self.sources_sigma, self.sources_sigma] ystddev_range = [self.sources_sigma, self.sources_sigma] table = make_random_gaussians(self.config.nsources, flux_range, xmean_range, ymean_range, xstddev_range, ystddev_range, random_state=12345) self.source_table = table data = make_gaussian_sources(self.config.shape, table) self.sources = Frame(data) # mask self.sources[self.rotation_mask] = 0.0 if self.config.plot: plotting.plot_box(self.sources, title="sources") # ----------------------------------------------------------------- def make_noise(self): """ This function ... :return: """ # Inform the user log.info("Making noise map ...") # Make noise data = make_noise_image(self.config.shape, type='gaussian', mean=0., stddev=self.config.noise_stddev, random_state=12345) self.noise = Frame(data) # Mask self.noise[self.rotation_mask] = 0.0 # Plot #if self.config.plot: plotting.plot_difference(self.frame, self.real_sky, title="original") if self.config.plot: plotting.plot_box(self.noise, title="noise") # ----------------------------------------------------------------- def make_galaxy(self): """ This function ... :return: """ # Inform the user log.info("Adding smooth galaxy source ...") effective_radius = self.config.galaxy_effective_radius effective_galaxy_angle = self.config.galaxy_angle + self.effective_rotation_angle axial_ratio = self.config.galaxy_axial_ratio angle_deg = effective_galaxy_angle.to("deg").value # Produce guess values initial_sersic_amplitude = self.config.galaxy_central_flux initial_sersic_r_eff = effective_radius initial_sersic_n = self.config.galaxy_sersic_index initial_sersic_x_0 = self.config.galaxy_position.x initial_sersic_y_0 = self.config.galaxy_position.y initial_sersic_ellip = (axial_ratio - 1.0) / axial_ratio initial_sersic_theta = np.deg2rad(angle_deg) # Produce sersic model from guess parameters, for time trials sersic_x, sersic_y = np.meshgrid(np.arange(self.xsize), np.arange(self.ysize)) sersic_model = Sersic2D(amplitude=initial_sersic_amplitude, r_eff=initial_sersic_r_eff, n=initial_sersic_n, x_0=initial_sersic_x_0, y_0=initial_sersic_y_0, ellip=initial_sersic_ellip, theta=initial_sersic_theta) sersic_map = sersic_model(sersic_x, sersic_y) # Set the galaxy frame self.galaxy = Frame(sersic_map) # Mask self.galaxy[self.rotation_mask] = 0.0 limit_radius = self.config.galaxy_relative_asymptotic_radius * effective_radius # Create galaxy region galaxy_center = PixelCoordinate(initial_sersic_x_0, initial_sersic_y_0) galaxy_radius = PixelStretch(limit_radius, limit_radius / axial_ratio) self.galaxy_region = PixelEllipseRegion(galaxy_center, galaxy_radius, effective_galaxy_angle) # Set galaxy map zero outside certain radius self.galaxy[self.galaxy_mask.inverse()] = 0.0 # Plot if self.config.plot: plotting.plot_box(self.galaxy, title="galaxy") # ----------------------------------------------------------------- def make_sky(self): """ This function ... :return: """ # Inform the user log.info("Making sky ...") # make constant sky self.make_constant_sky() # Make gradient sky self.make_gradient_sky() # ----------------------------------------------------------------- def make_constant_sky(self): """ This function .. :return: """ # Inform the user log.info("Making constant sky ...") self.constant_sky = Frame.filled_like(self.sources, self.config.constant_sky) # Mask self.constant_sky[self.rotation_mask] = 0.0 # Plot # ----------------------------------------------------------------- def make_gradient_sky(self): """ This function ... :return: """ # Inform the user log.info("Making gradient sky ...") y, x = np.mgrid[:self.ysize, :self.xsize] # Create gradient sky self.gradient_sky = Frame(x * y / 5000.) # Mask padded self.gradient_sky[self.rotation_mask] = 0.0 # Plot #if self.config.plot: plotting.plot_difference(self.frame, self.real_sky, title="frame with background") if self.config.plot: plotting.plot_box(self.gradient_sky, title="gradient sky") # ----------------------------------------------------------------- @lazyproperty def sky(self): """ This function ... :return: """ return self.constant_sky + self.gradient_sky # ----------------------------------------------------------------- @lazyproperty def frame(self): """ This fucntion ... :return: """ return self.sources_with_galaxy_and_noise + self.sky # ----------------------------------------------------------------- @lazyproperty def sources_with_noise(self): """ This function ... :return: """ return self.noise + self.sources # ----------------------------------------------------------------- @lazyproperty def sources_with_galaxy_and_noise(self): """ This function ... :return: """ return self.sources_with_noise + self.galaxy # ----------------------------------------------------------------- def mask_sources(self): """ This function ... :return: """ # Inform the user log.info("Masking sources ...") # Create sources mask mask = make_source_mask(self.sources_with_noise.data, snr=2, npixels=5, dilate_size=11, mask=self.rotation_mask) self.sources_mask = Mask(mask) # Plot if self.config.plot: plotting.plot_mask(self.sources_mask, title="sources mask") # ----------------------------------------------------------------- def calculate_statistics(self): """ This function ... :return: """ # Inform the user log.info("Calculating statistics ...") # Calculate statistics no sigma clipping self.calculate_statistics_no_clipping() # Calculate statistics clipping self.calculate_statistics_clipping() # Calculate statistics masked sources self.calculate_statistics_masked() # ----------------------------------------------------------------- def calculate_statistics_no_clipping(self): """ This function ... :return: """ # Compress (remove masked values) flattened = np.ma.array(self.sources_with_noise.data, mask=self.rotation_mask.data).compressed() median = np.median(flattened) biweight_loc = biweight_location(flattened) biweight_midvar = biweight_midvariance(flattened) median_absolute_deviation = mad_std(flattened) #print("median", median) #print("biweigth_loc", biweight_loc) #print("biweight_midvar", biweight_midvar) #print("median_absolute_deviation", median_absolute_deviation) self.statistics.no_clipping = Map() self.statistics.no_clipping.median = median self.statistics.no_clipping.biweight_loc = biweight_loc self.statistics.no_clipping.biweight_midvar = biweight_midvar self.statistics.no_clipping.median_absolute_deviation = median_absolute_deviation # SAME RESULTS: # median = np.median(self.original_frame) # biweight_loc = biweight_location(self.original_frame) # biweight_midvar = biweight_midvariance(self.original_frame) # median_absolute_deviation = mad_std(self.original_frame) # print("median", median) # print("biweigth_loc", biweight_loc) # print("biweight_midvar", biweight_midvar) # print("median_absolute_deviation", median_absolute_deviation) # ----------------------------------------------------------------- def calculate_statistics_clipping(self): """ This function ... :return: """ # Inform the user log.info("Sigma-clipping ...") # Sigma clip mean, median, std = sigma_clipped_stats(self.sources_with_noise.data, sigma=3.0, iters=5, mask=self.rotation_mask) #print("sigma-clip mean:", mean) #print("sigma-clip median:", median) #print("sigma-clip std:", std) self.statistics.clipping = Map() self.statistics.clipping.mean = mean self.statistics.clipping.median = median self.statistics.clipping.std = std # ----------------------------------------------------------------- def calculate_statistics_masked(self): """ This function ... :return: """ # Inform the user log.info("Calculating statistics with sources masked ...") # Statistics mean, median, std = sigma_clipped_stats(self.sources_with_noise.data, sigma=3.0, mask=self.total_mask.data, iters=5) #print("sigma-clip mean after source masking:", mean) #print("sigma-clip median after source masking:", median) #print("sigma_clip std after source masking:", std) # Set the statistics self.statistics.masked = Map() self.statistics.masked.mean = mean self.statistics.masked.median = median self.statistics.masked.std = std # ----------------------------------------------------------------- @lazyproperty def total_mask(self): """ This function ... :return: """ return self.sources_and_rotation_mask + self.galaxy_mask # ----------------------------------------------------------------- @lazyproperty def sources_and_rotation_mask(self): """ This function ... :return: """ return self.sources_mask + self.rotation_mask # ----------------------------------------------------------------- @lazyproperty def galaxy_mask(self): """ This function ... :return: """ # Make mask return self.galaxy_region.to_mask(self.xsize, self.ysize) # ----------------------------------------------------------------- @lazyproperty def reference_subtracted(self): """ This function ... :return: """ return self.frame - self.reference_sky # ----------------------------------------------------------------- @lazyproperty def subtracted(self): """ This function ... :return: """ return self.frame - self.estimated_sky # ----------------------------------------------------------------- @property def aperture_radius(self): """ This function ... :return: """ return self.config.fwhm * self.config.aperture_fwhm_factor # ----------------------------------------------------------------- @property def aperture_diameter(self): """ This function ... :return: """ return 2.0 * self.aperture_radius # ----------------------------------------------------------------- def reference(self): """ This function ... :return: """ # Inform the user log.info("Estimating background with photutils ...") # Plot total mask if self.config.plot: plotting.plot_mask(self.total_mask, title="total mask") integer_aperture_radius = int(math.ceil(self.aperture_radius)) box_shape = (integer_aperture_radius, integer_aperture_radius) filter_size = (3, 3) # Estimate the background sigma_clip = SigmaClip(sigma=3., iters=10) #bkg_estimator = MedianBackground() bkg_estimator = SExtractorBackground() bkg = Background2D(self.frame.data, box_shape, filter_size=filter_size, sigma_clip=sigma_clip, bkg_estimator=bkg_estimator, mask=self.total_mask.data) # Statistics #print("median background", bkg.background_median) #print("rms background", bkg.background_rms_median) self.statistics.reference = Map() self.statistics.reference.median = bkg.background_median self.statistics.reference.rms = bkg.background_rms_median # Plot if self.config.plot: plotting.plot_box(bkg.background, title="background from photutils") # Set the sky self.reference_sky = Frame(bkg.background) # Set bkg object self.photutils_bkg = bkg # Plot if self.config.plot: plotting.plot_box(self.reference_sky, title="reference sky") # ----------------------------------------------------------------- def subtract(self): """ This function ... :return: """ # Inform the user log.info("Subtracting the sky ...") # Settings settings = dict() settings["estimation"] = dict() settings["estimation"]["method"] = "photutils" settings["estimation"]["aperture_radius"] = self.aperture_radius settings["write"] = True #settings["estimation"]["finishing_step"] = "polynomial" #settings["estimation"]["polynomial_degree"] = self.config.polynomial_degree #settings["estimation"]["fill_method"] = "cubic" settings["plot"] = True # Input input_dict = dict() # Set input input_dict["frame"] = self.frame input_dict["principal_shape"] = self.galaxy_region input_dict["sources_mask"] = self.sources_mask input_dict["extra_mask"] = self.rotation_mask # Create command command = Command("subtract_sky", "subtract the sky from an artificially created image", settings, input_dict, cwd=self.subtraction_path) # Run the subtraction self.subtractor = self.run_command(command) # ----------------------------------------------------------------- @property def estimated_sky(self): """ This function ... :return: """ return self.subtractor.sky_frame # ----------------------------------------------------------------- @lazyproperty def subtracted(self): """ This function ... :return: """ return self.frame - self.estimated_sky # ----------------------------------------------------------------- @lazyproperty def sky_residual(self): """ This function ... :return: """ return self.estimated_sky - self.sky # ----------------------------------------------------------------- def write(self): """ This function ... :return: """ # Inform the user log.info("Writing ...") # Write the sources with noise self.write_sources() # Write the frame self.write_frame() # Write real sky map self.write_real_sky() # Write sources mask self.write_sources_mask() # Write galaxy mask self.write_galaxy_mask() # Write reference sky self.write_reference_sky() # Write estiamted sky self.write_estimated_sky() # Write residuals self.write_residual() # Write the statistics self.write_statistics() # ----------------------------------------------------------------- def write_sources(self): """ THis function ... :return: """ # Inform the user log.info("Writing the sources frame with noise ...") # Determine the path path = fs.join(self.path, "sources_noise.fits") # Save the frame self.sources_with_noise.saveto(path) # ----------------------------------------------------------------- def write_frame(self): """ This function ... :return: """ # Inform the user log.info("Writing the frame ...") # Determine the path path = fs.join(self.path, "frame.fits") # SAve the frame self.frame.saveto(path) # ----------------------------------------------------------------- def write_real_sky(self): """ This function ... :return: """ # Inform the user log.info("Writing the real sky map ...") # Determine the path path = fs.join(self.path, "real_sky.fits") # Save the map self.sky.saveto(path) # ----------------------------------------------------------------- def write_sources_mask(self): """ This function ... :return: """ # Inform the user log.info("Writing the sources mask ...") # Determine the path path = fs.join(self.path, "sources_mask.fits") # Save self.sources_mask.saveto(path) # ----------------------------------------------------------------- def write_galaxy_mask(self): """ This function ... :return: """ # Inform the user log.info("Writing the galaxy mask ...") # Determine the path path = fs.join(self.path, "galaxy_mask.fits") # Save self.galaxy_mask.saveto(path) # ----------------------------------------------------------------- def write_reference_sky(self): """ This function ... :return: """ # Inform the user log.info("Writing the reference sky map ...") # Determine the path path = fs.join(self.path, "reference_sky.fits") # Save self.reference_sky.saveto(path) # ----------------------------------------------------------------- def write_estimated_sky(self): """ This function ... :return: """ # Inform the user log.info("Writing the estimated sky map ...") # Determine the path path = fs.join(self.path, "estimated_sky.fits") # Save self.estimated_sky.saveto(path) # ----------------------------------------------------------------- def write_subtracted(self): """ This function ... :return: """ # Inform the user log.info("Writing the sky-subtracted frame ...") # Determine the path path = fs.join(self.path, "subtracted.fits") # Save self.subtracted.saveto(path) # ----------------------------------------------------------------- def write_residual(self): """ This function ... :return: """ # Inform the user log.info("Writing the residual map ...") # Determine the path path = fs.join(self.path, "residual.fits") # Save self.sky_residual.saveto(path) # ----------------------------------------------------------------- def write_statistics(self): """ This function ... :return: """ # Inform the user log.info("Writing the statistics ...") # Determine the path path = fs.join(self.path, "statistics.dat") # Write save_mapping(path, self.statistics) # ----------------------------------------------------------------- def plot(self): """ This function ... :return: """ # Inofmrthe user log.info("Plotting ...") # Plot meshes if self.config.plotting.meshes: self.plot_meshes() # ----------------------------------------------------------------- def plot_meshes(self): """ This function ... :return: """ # Inform the user log.info("Plotting the meshes ...") # Plot meshes plt.figure() norm = ImageNormalize(stretch=SqrtStretch()) plt.imshow(self.frame, origin='lower', cmap='Greys_r', norm=norm) self.photutils_bkg.plot_meshes(outlines=True, color='#1f77b4') plt.show()
plotter.config.max_nrows = 3 plotter.config.ngrids = 4 # Write data plotter.config.write = config.write_data # Crop to plotter.crop_to = environment.truncation_box # ----------------------------------------------------------------- # Loop over the frames in the current working directory for path, name in fs.files_in_cwd(extension="fits", returns=["path", "name"]): # Load the frame frame = Frame.from_file(path) # Get the filter fltr = frame.filter filter_name = str(fltr) # Do we have a photometry image for this filter if not environment.has_photometry_for_filter(fltr): continue # Get the photometry image reference_path = environment.photometry_image_paths_for_filters[fltr] reference = Frame.from_file(reference_path) # Add row plotter.add_row(reference, frame, filter_name)
paths = fs.files_in_path(galex_images_path, extension="fits", contains="poisson") + fs.files_in_path(sdss_images_path, extension="fits", contains="poisson") # Loop over the GALEX poisson frames for path in paths: # Image name name = fs.strip_extension(fs.name(path)) # Get instrument and band galaxy_name, instrument, band, _ = name.split("_") # Create the filter fltr = BroadBandFilter.from_instrument_and_band(instrument, band) # Load the frame poisson = Frame.from_file(path) # Get the attenuation att = attenuation.extinction_for_filter(fltr) # CORRECT FOR GALACTIC EXTINCTION poisson *= 10**(0.4 * att) # CONVERT UNIT to MJy/sr poisson *= 1e-6 poisson /= poisson.pixelarea.to("sr").value poisson.unit = "MJy/sr" # Make frame remote remote_frame = RemoteFrame.from_local(poisson, remote_host_id)
prep_names_column = [] names = ["Image name", "Image path", "Preparation name"] # Loop over all subdirectories of the data directory for path, name in fs.directories_in_path(fs.join(config.path, "data"), not_contains="bad", returns=["path", "name"]): # Loop over all FITS files found in the current subdirectory for image_path, image_name in fs.files_in_path(path, extension="fits", not_contains="_Error", returns=["path", "name"]): # Open the image frame frame = Frame.from_file(image_path) # Determine the preparation name if frame.filter is not None: prep_name = str(frame.filter) else: prep_name = image_name # Set the row entries names_column.append(image_name) paths_column.append(image_path) prep_names_column.append(prep_name) # Create the table data = [names_column, paths_column, prep_names_column] table = tables.new(data, names) # Check whether the preparation directory exists
definition.add_optional("alpha", "string", "alpha method", default_alpha_method, suggestions=alpha_methods) definition.add_flag("no_alpha", "no alpha", False) definition.add_optional("output", "string", "output filepath", letter="o") definition.add_optional("peak_alpha", "real", "alpha of peak value", 1.) definition.add_optional("max_npixels", "positive_integer", "maximum number of pixels") definition.add_optional("downsample", "positive_real", "downsample with this factor") definition.add_flag("show", "show after creating", False) config = parse_arguments("fits_to_png", definition) # ----------------------------------------------------------------- # Inform the user log.info("Loading the FITS file ...") # Load the FITS file frame = Frame.from_file(config.filename) # ----------------------------------------------------------------- if config.output is not None: filepath = fs.absolute_or_in(config.output, fs.cwd()) else: # Determine the path name = fs.strip_extension(fs.name(config.filename)) filepath = fs.absolute_path(name + ".png") # ----------------------------------------------------------------- # Max npixels if config.max_npixels is not None: