Ejemplo n.º 1
0
 def test_init(self):
     Aperture(8, 8, 4, data=self.test_data)
     # Non-integer indizes:
     Aperture(8.2, 8.3, 4, data=self.test_data)
     # Non-interger radius:
     with self.assertRaises(ValueError):
         Aperture(8.2, 8.3, 3.7, data=self.test_data)
Ejemplo n.º 2
0
def get_psf_variation(file,
                      index,
                      radius,
                      out_file=None,
                      normalize=None,
                      debug=False):
    if isinstance(index, list):
        if len(index) is 1:
            if index[0] is 0:
                logger.info(
                    f"Estimate image intensity peak and use as aperture index")
                image = fits.getdata(file)
                if image.ndim == 3:
                    image = np.sum(image, axis=0)
                index = np.unravel_index(np.argmax(image), image.shape)
                logger.info(f"Index is set to {index}")
            else:
                index = (index[0], index[0])
        index = tuple(index)

    if file is None:
        raise RuntimeError("No file was provided!")

    if out_file is None:
        out_file = "var_" + os.path.basename(file).replace(".fits", ".dat")

    # Initialize the aperture
    aperture = Aperture(index, radius, data=file, crop=True)
    if debug:
        imshow(aperture.get_integrated(), maximize=False)

    # Extract PSF profile
    logger.info(f"Extracting PSF profile from file {file}")
    xdata, ydata, edata = aperture.get_psf_variance()

    # Normalize profile
    if normalize == 'peak':
        ydata /= ydata[0]
        edata /= ydata[0]
    elif normalize == 'aperture':
        ydata /= ydata[-1]
        edata /= ydata[-1]
    elif normalize is not None:
        raise ValueError(
            "Normalize must be either 'peak', 'aperture, or None!'")

    # Save encircled energy data to outfile
    out_table = Table(data=[xdata, ydata, edata],
                      names=['Radius', 'Variance', 'dVariance'])
    logger.info(f"Store PSF profile to {out_file}")
    out_table.write(out_file, overwrite=True, format='ascii.fixed_width')
Ejemplo n.º 3
0
 def test_crop(self):
     aperture = Aperture(8, 8, 4, data=self.test_data, crop=True)
     aperture.crop()
     # imshow(aperture())
     aperture = Aperture(8, 8, 4, data=self.test_data, crop=False)
     # imshow(aperture())
     aperture.crop()
Ejemplo n.º 4
0
 def setUp(self):
     size = 256
     amp = np.ones((size, size))
     pha = np.random.rand(size, size) * 1e1
     # imshow(pha, title="Phase")
     amp = Aperture(128, 128, 64, data=amp, crop=False).data
     self.aperture = amp * np.exp(1j * pha)
Ejemplo n.º 5
0
def main(options=None):

    args = parser(options=options)

    # Interprete input
    args.index = tuple(args.index)

    if args.file is None:
        raise RuntimeError("No file was provided!")

    if args.outfile is None:
        outfile = os.path.basename(args.file)
        outfile = "psf_" + outfile.replace(".fits", ".dat")
        # outfile = os.path.join(args.outdir, outfile)

    # Initialize the aperture
    aperture = Aperture(args.index, args.radius, data=args.file, crop=True)
    # peak = aperture.get_aperture_peak()
    # aperture = Aperture(peak, args.radius, data=args.file, crop=True)
    if args.debug:
        imshow(aperture.get_integrated(), maximize=args.maximize)

    xdata, ydata = aperture.get_psf_profile()

    if args.normalize == 'peak':
        ydata /= ydata[0]
    elif args.normalize == 'aperture':
        ydata /= ydata[-1]
    elif args.normalize is not None:
        raise ValueError(
            "Normalize must be either 'peak', 'aperture, or None!'")

    # Save encircled energy data to outfile
    header = "Radius Flux"
    data = np.concatenate(([xdata], [ydata]), axis=0).transpose()
    np.savetxt(outfile, data, header=header)

    if args.debug:
        psf_profile_plot(outfile, maximize=args.maximize)
Ejemplo n.º 6
0
    def init_apertures(self, filename, shift=None):

        if shift is None:
            shift = (0, 0)

        apertures = []
        for star in self.star_table:
            apertures.append(
                Aperture(star['y'] - shift[0],
                         star['x'] - shift[1],
                         self.radius,
                         data=os.path.join(self.in_dir, filename),
                         mask='rectangular',
                         crop=True))
        return apertures
Ejemplo n.º 7
0
def get_noise_mask(frame, noise_reference_margin):
    """Create an annulus-like mask within a given aperture for measuring noise
    and (sky) background.

    Args:
        frame (np.ndarray):
            Image frame within which the mask is derived.
        noise_reference_margin (int):
            Width of the reference annulus in pixels.

    Returns:
        annulus_mask (np.ndarray, dtype=bool):
            Mask array, derived from the frame.
    """
    center = int((frame.shape[0] - 1) / 2)
    radius = center - noise_reference_margin
    tmp = Aperture(center, center, radius, data=frame, crop=False)
    annulus_mask = np.logical_not(tmp.data.mask)
    return annulus_mask
Ejemplo n.º 8
0
 def test_call(self):
     imshow(self.test_data)
     test_aperture = Aperture(8, 8, 4, data=self.test_data)
     imshow(test_aperture.data)
     test_aperture = Aperture(64, 64, 16, data=self.test_data_large)
     imshow(test_aperture.data)
Ejemplo n.º 9
0
 def test_encircled_energy(self):
     aperture = Aperture(8, 8, 4, data=self.test_data)
     aperture.get_encircled_energy(saveto='specklepy/tests/files/analysis/example_encircled_energy.dat')
Ejemplo n.º 10
0
 def setUp(self):
     size = 256
     amp = np.ones((size, size))
     amp = Aperture(128, 128, 64, data=amp, subset_only=False)().filled(0)
     pha = np.random.rand(size, size) * 2 * np.pi * 2**(-1)
     self.aperture = amp * np.exp(1j * pha)
Ejemplo n.º 11
0
def main(options=None):

    args = parser(options=options)

    # Interprete input
    args.index = tuple(args.index)

    if args.file is None:
        if args.Fourier_file is not None:
            start_with_Fourier_file = True
            logger.info("Starting from Fourier file {}.".format(
                args.Fourier_file))
            args.file = args.Fourier_file
        else:
            raise IOError(
                "At least one of --file or --Fourier_file have to be given!")
    else:
        start_with_Fourier_file = False
        # Apply default
        if args.Fourier_file is None:
            args.Fourier_file = args.file.replace(".fits", "_Fourier.fits")
    # Apply default
    if args.outfile is None:
        args.outfile = args.file.replace(".fits", ".dat")

    # Starting with the pre-analysis of the file
    if not start_with_Fourier_file:

        # Test of the heavy spot of the aperture
        aperture = Aperture(*args.index,
                            args.radius,
                            data=args.file,
                            crop=False)
        max = aperture.get_aperture_peak()
        if args.debug:
            imshow(aperture.data, title="Aperture in the integrated cube")
        if max == args.index:
            logger.info(
                "Index {} is identical with the maximum of the integrated cube image {}."
                .format(args.index, max))
        else:
            logger.info(
                "Index {} is not identical with the maximum of the integrated cube image {}."
                .format(args.index, max))
            answer = input(
                "Shall the index guess be replaced by the coordinates of the local maximum? (yes,no)"
            )
            if answer.lower() == "yes":
                logger.info(
                    "Replacing index {} by the maximum of the integrated cube image {}..."
                    .format(args.index, max))
                args.index = max
                aperture = Aperture(*args.index,
                                    args.radius,
                                    data=integrated_cube,
                                    mask=None,
                                    crop=True)
                if answer and (answer.lower() == "yes" or answer == ''):
                    if args.debug:
                        imshow(aperture.data, title="Updated aperture")
            else:
                logger.info("Continuing with the central index {}...".format(
                    args.index))

        # Remove margins from aperture
        aperture.remove_margins()
        logger.info("The aperture has shape {}.".format(aperture.data.shape))
        aperture.powerspec_to_file(args.file, args.Fourier_file)
        del aperture

    # Show interim results
    Fourier_cube = fits.getdata(args.Fourier_file)
    Fourier_mean = np.mean(Fourier_cube, axis=0)
    Fourier_var = np.var(
        Fourier_cube,
        axis=0)  # Compute variance to average linearly in the following
    if args.debug:
        imshow(
            Fourier_mean,
            title="Mean of the Fourier transformed cube along the time axis",
            norm=LogNorm())
        imshow(
            np.sqrt(Fourier_var),
            title=
            "Standard deviation in the Fourier transformed cube along the time axis",
            norm=LogNorm())

    # Compute Fourier radius map and mask
    center = (Fourier_mean.shape[0] / 2, Fourier_mean.shape[1] / 2)
    xx, yy = np.mgrid[:Fourier_mean.shape[0], :Fourier_mean.shape[1]]
    Fourier_radius = np.sqrt(
        np.square(xx - center[0]) + np.square(yy - center[1]))
    Fourier_radius = np.ma.masked_greater(Fourier_radius, center[0])
    Fourier_mean = np.ma.masked_array(Fourier_mean, mask=Fourier_radius.mask)
    Fourier_var = np.ma.masked_array(Fourier_var, mask=Fourier_radius.mask)

    # Average azimuthally
    logger.info("Averaging the Fourier plane azimuthally")
    Fourier_radius = Fourier_radius.reshape((-1))
    Fourier_mean = Fourier_mean.reshape((-1))
    Fourier_var = Fourier_var.reshape((-1))

    xdata = np.unique(Fourier_radius)
    ydata = np.zeros(xdata.shape)
    edata = np.zeros(xdata.shape)
    for index, value in enumerate(xdata):
        ydata[index] = np.mean(Fourier_mean[np.where(Fourier_radius == value)])
        edata[index] = np.mean(Fourier_var[np.where(Fourier_radius == value)])
    # Turn variance into standard deviation
    edata = np.sqrt(edata)

    if args.pixel_scale is not None:
        logger.warn("Handling the pixel scale is not implemented yet!")

    if args.debug:
        plot_simple(xdata,
                    ydata,
                    title="{}\nCenter={} Radius={}".format(
                        args.Fourier_file, args.index, args.radius),
                    xlabel="Fourier radius")

    # Save power spectra to outfile
    caption = "Fourier_radius mean std"
    data = np.concatenate(([xdata], [ydata], [edata]), axis=0).transpose()
    np.savetxt(args.outfile, data, header=caption)
Ejemplo n.º 12
0
 def init_ref_apertures(self, filename, shift=(0, 0)):
     self.ref_apertures = []
     for star in self.star_table:
         # print(star['x'], star['y'], self.radius, filename)
         self.ref_apertures.append(Aperture(star['y'] + shift[0], star['x'] + shift[1], self.radius, data=filename, subset_only=True, verbose=False))