Exemple #1
0
    def centroid_com(self):
        """
        This function ...
        :return:
        """

        return centroid_com(self._data)
Exemple #2
0
def get_centroids(cube):
	p = progbar(15, "computing centroids")
	tot = cube.shape[0]
	s = tot / 15
	im = cube[0]
	x0 = y0 = 12
	x1 = y1 = 19
	mask = np.repeat(True, im.size).reshape(im.shape)
	mask[x0:x1,y0:y1] = False
	centroid = []
	for k,im in enumerate(cube):
		ma = np.ma.masked_array(im, mask)
		masked = ma.filled(0)
		centroid.append(centroid_com(masked))
		if (k+1) % s == 0: p.write()
	p.close()
	centroid = np.array(centroid)
	return centroid
Exemple #3
0
def recenter(image, pos, window_size=15, method="2dg"):
    """
    Recenter each star in each frame of the image cube before performing
    aperture photometry to take care of slight misalignments between frames
    because of atmospheric turbulence and tracking/pointing errors.
        
    Parameters
    ----------
    image : numpy array
        2D image
        
    pos : list
        List of (x,y) tuples for star positions
            
    window_size : int
        Window size in which to fit the gaussian to the star to calculate
        new center
        
    method : string
        Method used to find center of the star. Options are 1d Gaussian fit,
        2d gaussian fit or com (center of mass)    
                    
    Returns
    -------
    xcen, ycen : float
        Source x and y centers               
    """
    pos = np.asarray(pos)

    ny, nx = image.shape
    window_size = int(window_size)
    nstars = pos.shape[0]

    star_pos = np.zeros([nstars, 2], dtype=np.float32)
    for i in range(nstars):
        x, y = pos[i][0], pos[i][1]

        xmin, xmax = int(x) - int(window_size / 2), int(x) + int(window_size / 2) + 1
        ymin, ymax = int(y) - int(window_size / 2), int(y) + int(window_size / 2) + 1

        if xmin < 0:
            xmin = 0

        if ymin < 0:
            ymin = 0

        if xmax > nx:
            xmax = nx

        if ymax > ny:
            ymax = ny

        if method == "1dg":
            xcen, ycen = centroid_1dg(image[ymin:ymax, xmin:xmax])
        elif method == "2dg":
            xcen, ycen = centroid_2dg(image[ymin:ymax, xmin:xmax])
        elif method == "com":
            xcen, ycen = centroid_com(image[ymin:ymax, xmin:xmax])

        if (np.abs(xmin + xcen - x)) > 3.0 or (np.abs(ymin + ycen - y)) > 3.0:
            star_pos[i, 0] = x
            star_pos[i, 1] = y
        else:
            star_pos[i, 0] = xmin + xcen
            star_pos[i, 1] = ymin + ycen

    return star_pos
Exemple #4
0
def photometry(image_paths, master_dark_path, master_flat_path,
               target_centroid, comparison_flux_threshold, aperture_radii,
               centroid_stamp_half_width, psf_stddev_init,
               aperture_annulus_radius, output_path):
    """
    Parameters
    ----------
    master_dark_path : str
        Path to master dark frame
    master_flat_path :str
        Path to master flat field
    target_centroid : `~numpy.ndarray`
        position of centroid, with shape (2, 1)
    comparison_flux_threshold : float
        Minimum fraction of the target star flux required to accept for a
        comparison star to be included
    aperture_radii : `~numpy.ndarray`
        Range of aperture radii to use
    centroid_stamp_half_width : int
        Centroiding is done within image stamps centered on the stars. This
        parameter sets the half-width of the image stamps.
    psf_stddev_init : float
        Initial guess for the width of the PSF stddev parameter, used for
        fitting 2D Gaussian kernels to the target star's PSF.
    aperture_annulus_radius : int
        For each aperture in ``aperture_radii``, measure the background in an
        annulus ``aperture_annulus_radius`` pixels bigger than the aperture
        radius
    output_path : str
        Path to where outputs will be saved.
    """
    master_dark = fits.getdata(master_dark_path)
    master_flat = fits.getdata(master_flat_path)

    star_positions = init_centroids(image_paths[0],
                                    master_flat,
                                    master_dark,
                                    target_centroid,
                                    plots=True,
                                    min_flux=comparison_flux_threshold).T

    # Initialize some empty arrays to fill with data:
    times = np.zeros(len(image_paths))
    fluxes = np.zeros(
        (len(image_paths), len(star_positions), len(aperture_radii)))
    errors = np.zeros(
        (len(image_paths), len(star_positions), len(aperture_radii)))
    xcentroids = np.zeros((len(image_paths), len(star_positions)))
    ycentroids = np.zeros((len(image_paths), len(star_positions)))
    airmass = np.zeros(len(image_paths))
    airpress = np.zeros(len(image_paths))
    humidity = np.zeros(len(image_paths))
    telfocus = np.zeros(len(image_paths))
    psf_stddev = np.zeros(len(image_paths))

    medians = np.zeros(len(image_paths))

    with ProgressBar(len(image_paths)) as bar:
        for i in range(len(image_paths)):
            bar.update()

            # Subtract image by the dark frame, normalize by flat field
            #imagedata = (rebin_image(fits.getdata(image_paths[i]), 2) - master_dark[:-1, :-1]) / master_flat[:-1, :-1]
            imagedata = (fits.getdata(image_paths[i]) -
                         master_dark) / master_flat

            # Collect information from the header
            imageheader = fits.getheader(image_paths[i])
            exposure_duration = imageheader['EXPTIME']
            times[i] = Time(imageheader['DATE-OBS'],
                            format='isot',
                            scale='utc').jd
            medians[i] = np.median(imagedata)
            airmass[i] = imageheader['AIRMASS']
            airpress[i] = imageheader['AIRPRESS']
            humidity[i] = imageheader['HUMIDITY']
            telfocus[i] = imageheader['TELFOCUS']

            # Initial guess for each stellar centroid informed by previous centroid
            for j in range(len(star_positions)):
                if i == 0:
                    init_x = star_positions[j][0]
                    init_y = star_positions[j][1]
                else:
                    init_x = ycentroids[i - 1][j]
                    init_y = xcentroids[i - 1][j]

                # Cut out a stamp of the full image centered on the star
                image_stamp = imagedata[init_y -
                                        centroid_stamp_half_width:init_y +
                                        centroid_stamp_half_width, init_x -
                                        centroid_stamp_half_width:init_x +
                                        centroid_stamp_half_width]

                # Measure stellar centroid with 2D gaussian fit
                x_stamp_centroid, y_stamp_centroid = centroid_com(image_stamp)
                y_centroid = x_stamp_centroid + init_x - centroid_stamp_half_width
                x_centroid = y_stamp_centroid + init_y - centroid_stamp_half_width

                xcentroids[i, j] = x_centroid
                ycentroids[i, j] = y_centroid

                # import matplotlib.pyplot as plt
                # plt.figure()
                # plt.imshow(np.log(image_stamp), origin='lower', cmap=plt.cm.viridis)
                # plt.scatter(x_stamp_centroid, y_stamp_centroid, s=30)
                # plt.show()
                #
                # plt.figure()
                # s = np.std(imagedata)
                # m = np.median(imagedata)
                # plt.imshow(imagedata, origin='lower', cmap=plt.cm.viridis,
                #            vmin=m-2*s, vmax=m+2*s)
                # plt.show()

                # For the target star, measure PSF:
                if j == 0:
                    psf_model_init = models.Gaussian2D(
                        amplitude=np.max(image_stamp),
                        x_mean=centroid_stamp_half_width,
                        y_mean=centroid_stamp_half_width,
                        x_stddev=psf_stddev_init,
                        y_stddev=psf_stddev_init)

                    fit_p = fitting.LevMarLSQFitter()
                    y, x = np.mgrid[:image_stamp.shape[0], :image_stamp.
                                    shape[1]]
                    best_psf_model = fit_p(
                        psf_model_init, x, y,
                        image_stamp - np.median(image_stamp))
                    psf_stddev[i] = 0.5 * (best_psf_model.x_stddev.value +
                                           best_psf_model.y_stddev.value)

            positions = np.vstack([ycentroids[i, :], xcentroids[i, :]])

            for k, aperture_radius in enumerate(aperture_radii):
                target_apertures = CircularAperture(positions, aperture_radius)
                background_annuli = CircularAnnulus(
                    positions,
                    r_in=aperture_radius + aperture_annulus_radius,
                    r_out=aperture_radius + 2 * aperture_annulus_radius)
                flux_in_annuli = aperture_photometry(
                    imagedata, background_annuli)['aperture_sum'].data
                background = flux_in_annuli / background_annuli.area()
                flux = aperture_photometry(
                    imagedata, target_apertures)['aperture_sum'].data
                background_subtracted_flux = (
                    flux - background * target_apertures.area())

                fluxes[i, :,
                       k] = background_subtracted_flux / exposure_duration
                errors[i, :, k] = np.sqrt(flux)

    ## Save some values
    results = PhotometryResults(times, fluxes, errors, xcentroids, ycentroids,
                                airmass, airpress, humidity, medians,
                                psf_stddev, aperture_radii)
    results.save(output_path)
    return results
Exemple #5
0
def photometry(star_positions, aperture_radii, centroid_stamp_half_width,
               psf_stddev_init, aperture_annulus_radius, output_path):
    """
    Parameters
    ----------
    master_dark_path : str
        Path to master dark frame
    master_flat_path :str
        Path to master flat field
    target_centroid : `~numpy.ndarray`
        position of centroid, with shape (2, 1)
    comparison_flux_threshold : float
        Minimum fraction of the target star flux required to accept for a
        comparison star to be included
    aperture_radii : `~numpy.ndarray`
        Range of aperture radii to use
    centroid_stamp_half_width : int
        Centroiding is done within image stamps centered on the stars. This
        parameter sets the half-width of the image stamps.
    psf_stddev_init : float
        Initial guess for the width of the PSF stddev parameter, used for
        fitting 2D Gaussian kernels to the target star's PSF.
    aperture_annulus_radius : int
        For each aperture in ``aperture_radii``, measure the background in an
        annulus ``aperture_annulus_radius`` pixels bigger than the aperture
        radius
    output_path : str
        Path to where outputs will be saved.
    """
    master_dark = fits.getdata(master_dark_path)
    master_flat = fits.getdata(master_flat_path)

    master_flat[master_flat < 0.1] = 1.0 # tmp

    #star_positions = init_centroids(image_paths[0:3], master_flat, master_dark,
    #                                target_centroid, plots=True,
    #                                min_flux=comparison_flux_threshold).T

    # Initialize some empty arrays to fill with data:
    times = np.zeros(len(image_paths))
    fluxes = np.zeros((len(image_paths), len(star_positions),
                       len(aperture_radii)))
    errors = np.zeros((len(image_paths), len(star_positions),
                       len(aperture_radii)))
    xcentroids = np.zeros((len(image_paths), len(star_positions)))
    ycentroids = np.zeros((len(image_paths), len(star_positions)))
    airmass = np.zeros(len(image_paths))
    airpress = np.zeros(len(image_paths))
    humidity = np.zeros(len(image_paths))
    telfocus = np.zeros(len(image_paths))
    psf_stddev = np.zeros(len(image_paths))

    medians = np.zeros(len(image_paths))

    with ProgressBar(len(image_paths)) as bar:
        for i in range(len(image_paths)):
            bar.update()

            # Subtract image by the dark frame, normalize by flat field
            imagedata = (fits.getdata(image_paths[i]) - master_dark) / master_flat

            # Collect information from the header
            imageheader = fits.getheader(image_paths[i])
            exposure_duration = imageheader['EXPTIME']
            times[i] = Time(imageheader['DATE-OBS'], format='isot', scale=imageheader['TIMESYS'].lower()).jd
            medians[i] = np.median(imagedata)
            airmass[i] = imageheader['AIRMASS']
            airpress[i] = imageheader['AIRPRESS']
            humidity[i] = imageheader['HUMIDITY']
            telfocus[i] = imageheader['TELFOCUS']

            # Initial guess for each stellar centroid informed by previous centroid
            for j in range(len(star_positions)):
                if i == 0:
                    init_x = star_positions[j][0]
                    init_y = star_positions[j][1]
                else:
                    init_x = ycentroids[i-1][j]
                    init_y = xcentroids[i-1][j]

                # Cut out a stamp of the full image centered on the star
                image_stamp = imagedata[int(init_y) - centroid_stamp_half_width:
                                        int(init_y) + centroid_stamp_half_width,
                                        int(init_x) - centroid_stamp_half_width:
                                        int(init_x) + centroid_stamp_half_width]

                # Measure stellar centroid with 2D gaussian fit
                x_stamp_centroid, y_stamp_centroid = centroid_com(image_stamp)
                y_centroid = x_stamp_centroid + init_x - centroid_stamp_half_width
                x_centroid = y_stamp_centroid + init_y - centroid_stamp_half_width

                xcentroids[i, j] = x_centroid
                ycentroids[i, j] = y_centroid

                # For the target star, measure PSF:
                if j == 0:
                    psf_model_init = models.Gaussian2D(amplitude=np.max(image_stamp),
                                                       x_mean=centroid_stamp_half_width,
                                                       y_mean=centroid_stamp_half_width,
                                                       x_stddev=psf_stddev_init,
                                                       y_stddev=psf_stddev_init)

                    fit_p = fitting.LevMarLSQFitter()
                    y, x = np.mgrid[:image_stamp.shape[0], :image_stamp.shape[1]]
                    best_psf_model = fit_p(psf_model_init, x, y, image_stamp -
                                           np.median(image_stamp))
                    psf_stddev[i] = 0.5*(best_psf_model.x_stddev.value +
                                          best_psf_model.y_stddev.value)

            positions = np.vstack([ycentroids[i, :], xcentroids[i, :]])

            for k, aperture_radius in enumerate(aperture_radii):
                target_apertures = CircularAperture(positions, aperture_radius)
                background_annuli = CircularAnnulus(positions,
                                                    r_in=aperture_radius +
                                                         aperture_annulus_radius,
                                                    r_out=aperture_radius +
                                                          2 * aperture_annulus_radius)
                flux_in_annuli = aperture_photometry(imagedata,
                                                     background_annuli)['aperture_sum'].data
                background = flux_in_annuli/background_annuli.area()
                flux = aperture_photometry(imagedata,
                                           target_apertures)['aperture_sum'].data
                background_subtracted_flux = (flux - background *
                                              target_apertures.area())

                fluxes[i, :, k] = background_subtracted_flux/exposure_duration
                errors[i, :, k] = np.sqrt(flux)

    ## Save some values
    results = PhotometryResults(times, fluxes, errors, xcentroids, ycentroids,
                                airmass, airpress, humidity, medians,
                                psf_stddev, aperture_radii)
    results.save(output_path)
    return results