示例#1
0
def commonbeam(major1, minor1, pa1, major2, minor2, pa2):
    """
    Create a smallest bounding ellipse around two other ellipses.
    Give ellipse dimensions as astropy units quantities.
    """
    major1 = ucheck(major1, unit=u.deg)
    minor1 = ucheck(minor1, unit=u.deg)
    pa1 = ucheck(pa1, unit=u.deg)
    major2 = ucheck(major2, unit=u.deg)
    minor2 = ucheck(minor2, unit=u.deg)
    pa2 = ucheck(pa2, unit=u.deg)

    somebeams = Beams([major1.to(u.arcsec), major2.to(u.arcsec)]*u.arcsec,
                      [minor1.to(u.arcsec), minor2.to(u.arcsec)]*u.arcsec,
                      [pa1, pa2]*u.deg)

    for tolerance in (1e-4, 5e-5, 1e-5, 1e-6, 1e-7):
        try:
            common = somebeams.common_beam(tolerance=tolerance)
            break
        except BeamError:
            continue

    new_major = common._major
    new_minor = common._minor
    new_pa = common._pa

    return new_major.to(u.deg), new_minor.to(u.deg), new_pa
示例#2
0
    def common_beam(self, circbeam=True):
        """
        Return parameters of the smallest common beam
        Parameters
        ----------
        circbeam: bool, optional. Default True - force beam circular

        Returns
        -------
        bmaj, bmin, bpa: beam in deg

        """
        if circbeam:
            maxmaj = np.max([image.get_beam()[0] for image in self.images])
            target_beam = [maxmaj * 1.01, maxmaj * 1.01,
                           0.]  # add 1% to prevent crash in convolution
        else:
            from radio_beam import Beams
            my_beams = Beams([image.get_beam()[0]
                              for image in self.images] * u.deg,
                             [image.get_beam()[1]
                              for image in self.images] * u.deg,
                             [image.get_beam()[2]
                              for image in self.images] * u.deg)
            common_beam = my_beams.common_beam()
            target_beam = [
                common_beam.major.to_value('deg'),
                common_beam.minor.to_value('deg'),
                common_beam.pa.to_value('deg')
            ]
        return target_beam
示例#3
0
文件: utils.py 项目: mccbc/nrao
def commonbeam(major1, minor1, pa1, major2, minor2, pa2):
    """
    Create a smallest bounding ellipse around two other ellipses. Give ellipse dimensions as astropy units quantities.
    """
    somebeams = Beams([major1.to(u.arcsec), major2.to(u.arcsec)] * u.arcsec, [minor1.to(u.arcsec), minor2.to(u.arcsec)] * u.arcsec, [pa1.to(u.deg), pa2.to(u.deg)] * u.deg)
    common = somebeams.common_beam()
    new_major = common._major
    new_minor = common._minor
    new_pa = common._pa
    return new_major.to(u.deg), new_minor.to(u.deg), new_pa
示例#4
0
def getmaxbeam(files, verbose=False):
    """Get largest beam
    """
    beams = []
    for file in files:
        header = fits.getheader(file, memmap=True)
        beam = Beam.from_fits_header(header)
        beams.append(beam)

    beams = Beams([beam.major.value for beam in beams] * u.deg,
                  [beam.minor.value for beam in beams] * u.deg,
                  [beam.pa.value for beam in beams] * u.deg)

    return beams.common_beam()
示例#5
0
文件: amos.py 项目: apertif/amosaic
def get_common_psf(fitsfiles):
    """ common psf for the list of fits files """
    beams = []
    bmajes = []
    bmines = []
    bpas = []
    for f in fitsfiles:
        ih = fits.getheader(f)
        bmajes.append(ih['BMAJ'])
        bmines.append(ih['BMIN'])
        bpas.append(ih['BPA'])
        beam = Beam.from_fits_header(ih)
        beams.append(beam)
    beams = Beams(bmajes * u.deg, bmines * u.deg, bpas * u.deg)
    common = beams.common_beam()
    smallest = beams.smallest_beam()
    logging.info('Smallest PSF: %s', smallest)
    logging.info('Common PSF: %s', common)
    return common
示例#6
0
文件: makecube.py 项目: gheald/quocka
def getmaxbeam(data_dict,
               band,
               cutoff=15 * u.arcsec,
               tolerance=0.0001,
               nsamps=200,
               epsilon=0.0005,
               verbose=False,
               debug=False):
    """Find common beam.

    Arguments:
        data_dict {dict} -- Dict containing fits files.
        band {int} -- ATCA band name.

    Keyword Arguments:
        tolerance {float} -- See common_beam (default: {0.0001})
        nsamps {int} -- See common_beam (default: {200})
        epsilon {float} -- See common_beam (default: {0.0005})
        verbose {bool} -- Verbose output (default: {False})
        debug {bool} -- Show dubugging plots (default: {False})

    Returns:
        beam_dict {dict} -- Beam and frequency data.
    """
    files = data_dict[band]
    stokes = ['i', 'q', 'u', 'v']
    beam_dict = {}
    for stoke in stokes:
        beams = []
        freqs = []
        for file in files[stoke]:
            header = fits.getheader(file, memmap=True)
            freqs.append(header['CRVAL3'])
            beam = Beam.from_fits_header(header)
            beams.append(beam)
        beams = Beams([beam.major.value for beam in beams] * u.deg,
                      [beam.minor.value for beam in beams] * u.deg,
                      [beam.pa.value for beam in beams] * u.deg)
        flags = beams.major > cutoff
        beam_dict.update({
            stoke + '_beams': beams,
            stoke + '_freqs': np.array(freqs) * u.Hz,
            stoke + '_flags': flags
        })
    if debug:
        plt.figure()
        plt.title(band)
        for stoke in stokes:
            idx = [not flag for flag in beam_dict[stoke + '_flags']]
            plt.plot(beam_dict[stoke + '_freqs'][idx],
                     beam_dict[stoke + '_beams'].major.to(u.arcsec)[idx],
                     '.',
                     alpha=0.5,
                     label=stoke + '--BMAJ')

        plt.plot(beam_dict[stoke + '_freqs'][idx],
                 beam_dict[stoke + '_beams'].minor.to(u.arcsec)[idx],
                 '.',
                 alpha=0.5,
                 label=stoke + '--BMIN')
        plt.xlabel('Frequency [Hz]')
        plt.ylabel('Beam size [arcsec]')
        plt.legend()
        plt.show()

    bmaj = []
    bmin = []
    bpa = []
    for stoke in stokes:
        bmaj += list(beam_dict[f'{stoke}_beams'].major.
                     value[~beam_dict[f'{stoke}_flags']])
        bmin += list(beam_dict[f'{stoke}_beams'].minor.
                     value[~beam_dict[f'{stoke}_flags']])
        bpa += list(
            beam_dict[f'{stoke}_beams'].pa.value[~beam_dict[f'{stoke}_flags']])

    big_beams = Beams(bmaj * u.deg, bmin * u.deg, bpa * u.deg)

    try:
        cmn_beam = big_beams.common_beam(tolerance=tolerance,
                                         epsilon=epsilon,
                                         nsamps=nsamps)
    except BeamError:
        if verbose:
            print("Couldn't find common beam with defaults")
            print("Trying again with smaller tolerance")
        cmn_beam = big_beams.common_beam(tolerance=tolerance * 0.1,
                                         epsilon=epsilon,
                                         nsamps=nsamps)

    cmn_beam = Beam(
        major=my_ceil(cmn_beam.major.to(u.arcsec).value, precision=1) *
        u.arcsec,
        minor=my_ceil(cmn_beam.minor.to(u.arcsec).value, precision=1) *
        u.arcsec,
        pa=round_up(cmn_beam.pa.to(u.deg), decimals=2))

    target_header = fits.getheader(data_dict[band]['i'][0], memmap=True)
    dx = target_header['CDELT1'] * -1 * u.deg
    dy = target_header['CDELT2'] * u.deg
    grid = dy
    conbeams = [cmn_beam.deconvolve(beam) for beam in big_beams]

    # Check that convolving beam will be nyquist sampled
    min_samps = []
    for b_idx, conbeam in enumerate(conbeams):
        # Get maj, min, pa
        samp = conbeam.minor / grid.to(u.arcsec)
        if samp < 2:
            min_samps.append([samp, b_idx])

    if len(min_samps) > 0:
        print('Adjusting common beam to be sampled by grid!')
        worst_idx = np.argmin([samp[0] for samp in min_samps], axis=0)
        samp_cor_fac, idx = 2 / \
            min_samps[worst_idx][0], int(
                min_samps[worst_idx][1])
        conbeam = conbeams[idx]
        major = conbeam.major
        minor = conbeam.minor * samp_cor_fac
        pa = conbeam.pa
        # Check for small major!
        if major < minor:
            major = minor
            pa = 0 * u.deg

        cor_beam = Beam(major, minor, pa)
        if verbose:
            print('Smallest common beam is:', cmn_beam)
        cmn_beam = big_beams[idx].convolve(cor_beam)
        cmn_beam = Beam(
            major=my_ceil(cmn_beam.major.to(u.arcsec).value, precision=1) *
            u.arcsec,
            minor=my_ceil(cmn_beam.minor.to(u.arcsec).value, precision=1) *
            u.arcsec,
            pa=round_up(cmn_beam.pa.to(u.deg), decimals=2))
        if verbose:
            print('Smallest common Nyquist sampled beam is:', cmn_beam)
    if debug:
        from matplotlib.patches import Ellipse
        pixscale = 1 * u.arcsec
        fig = plt.figure()
        ax = plt.gca()
        for beam in big_beams:
            ellipse = Ellipse(
                (0, 0),
                width=(beam.major.to(u.deg) / pixscale).to(
                    u.dimensionless_unscaled).value,
                height=(beam.minor.to(u.deg) / pixscale).to(
                    u.dimensionless_unscaled).value,
                # PA is 90 deg offset from x-y axes by convention
                # (it is angle from NCP)
                angle=(beam.pa + 90 * u.deg).to(u.deg).value,
                edgecolor='k',
                fc='None',
                lw=1,
                alpha=0.1)
            ax.add_artist(ellipse)
        ellipse = Ellipse(
            (0, 0),
            width=(cmn_beam.major.to(u.deg) / pixscale).to(
                u.dimensionless_unscaled).value,
            height=(cmn_beam.minor.to(u.deg) / pixscale).to(
                u.dimensionless_unscaled).value,
            # PA is 90 deg offset from x-y axes by convention
            # (it is angle from NCP)
            angle=(cmn_beam.pa + 90 * u.deg).to(u.deg).value,
            edgecolor='r',
            fc='None',
            lw=2,
            alpha=1,
        )
        ax.add_artist(ellipse)
        label = f"BMAJ={cmn_beam.major.to(u.arcsec).round()}, BMIN={cmn_beam.minor.to(u.arcsec).round()}, BPA={cmn_beam.pa.to(u.deg).round()}"
        plt.plot([np.nan], [np.nan], 'r', label=label)
        plt.xlim(-0.2 * 60, 0.2 * 60)
        plt.ylim(-0.2 * 60, 0.2 * 60)
        plt.xlabel('$\Delta$ RA [arcsec]')
        plt.ylabel('$\Delta$ DEC [arcsec]')
        plt.legend()
        plt.show()

    beam_dict.update({'common_beam': cmn_beam})
    return beam_dict
示例#7
0
        else:
            raise FileNotFoundError(
                f'SI error image {si_err_image} does not exist.')
    #####################################################
    # find the smallest common beam
    if args.beam is None:
        if args.circbeam:
            maxmaj = np.max([b[0] for b in all_beams])
            target_beam = [maxmaj * 1.01, maxmaj * 1.01,
                           0.]  # add 1% to prevent crash in convolution
        else:
            from radio_beam import Beams
            my_beams = Beams([b[0] for b in all_beams] * u.deg,
                             [b[1] for b in all_beams] * u.deg,
                             [b[2] for b in all_beams] * u.deg)
            common_beam = my_beams.common_beam()
            target_beam = [
                common_beam.major.value, common_beam.minor.value,
                common_beam.pa.value
            ]
    else:
        target_beam = [
            args.beam[0] / 3600., args.beam[1] / 3600., args.beam[2]
        ]

    logging.info('Final beam: %.1f" %.1f" (pa %.1f deg)' \
        % (target_beam[0]*3600., target_beam[1]*3600., target_beam[2]))

    #####################################################
    # Generate regrid headers
    rwcs = pywcs(naxis=2)
示例#8
0
def getmaxbeam(file_dict,
               tolerance=0.0001,
               nsamps=200,
               epsilon=0.0005,
               verbose=False):
    """Find common beam

    Arguments:
        file_dict {dict} -- Filenames for each bandcube.

    Keyword Arguments:
        tolerance {float} -- See common_beam (default: {0.0001})
        nsamps {int} -- See common_beam (default: {200})
        epsilon {float} -- See common_beam (default: {0.0005})
        verbose {bool} -- Verbose output (default: {False})

    Returns:
        cmn_beam {Beam} -- Common beam
    """
    if verbose:
        print('Finding common beam...')
    stokes = ['i', 'q', 'u', 'v']
    beam_dict = {}
    beams = []
    for stoke in stokes:
        for i, file in enumerate(file_dict[stoke]):
            header = fits.getheader(file, memmap=True)
            if stoke == 'i' and i == 0:
                target_header = header
            beam = Beam.from_fits_header(header)
            beams.append(beam)
    beams = Beams([beam.major.value for beam in beams] * u.deg,
                  [beam.minor.value for beam in beams] * u.deg,
                  [beam.pa.value for beam in beams] * u.deg)

    try:
        cmn_beam = beams.common_beam(tolerance=tolerance,
                                     epsilon=epsilon,
                                     nsamps=nsamps)
    except BeamError:
        if verbose:
            print("Couldn't find common beam with defaults")
            print("Trying again with smaller tolerance")
        cmn_beam = beams.common_beam(tolerance=tolerance * 0.1,
                                     epsilon=epsilon,
                                     nsamps=nsamps)
    cmn_beam = Beam(
        major=my_ceil(cmn_beam.major.to(u.arcsec).value, precision=0) *
        u.arcsec,
        minor=my_ceil(cmn_beam.minor.to(u.arcsec).value, precision=0) *
        u.arcsec,
        pa=round_up(cmn_beam.pa.to(u.deg), decimals=2))
    dx = target_header['CDELT1'] * -1 * u.deg
    dy = target_header['CDELT2'] * u.deg
    assert abs(dx) == abs(dy)
    grid = dy
    conbeams = [cmn_beam.deconvolve(beam) for beam in beams]

    # Check that convolving beam will be nyquist sampled
    min_samps = []
    for b_idx, conbeam in enumerate(conbeams):
        # Get maj, min, pa
        samp = conbeam.minor / grid.to(u.arcsec)
        if samp < 2:
            min_samps.append([samp, b_idx])

    if len(min_samps) > 0:
        print('Adjusting common beam to be sampled by grid!')
        worst_idx = np.argmin([samp[0] for samp in min_samps], axis=0)
        samp_cor_fac, idx = 2 / \
            min_samps[worst_idx][0], int(
                min_samps[worst_idx][1])
        conbeam = conbeams[idx]
        major = conbeam.major
        minor = conbeam.minor * samp_cor_fac
        pa = conbeam.pa
        # Check for small major!
        if major < minor:
            major = minor
            pa = 0 * u.deg

        cor_beam = Beam(major, minor, pa)
        if verbose:
            print('Smallest common beam is:', cmn_beam)
        cmn_beam = beams[idx].convolve(cor_beam)
        cmn_beam = Beam(
            major=my_ceil(cmn_beam.major.to(u.arcsec).value, precision=1) *
            u.arcsec,
            minor=my_ceil(cmn_beam.minor.to(u.arcsec).value, precision=1) *
            u.arcsec,
            pa=round_up(cmn_beam.pa.to(u.deg), decimals=2))
        if verbose:
            print('Smallest common Nyquist sampled beam is:', cmn_beam)
    return cmn_beam