예제 #1
0
def test_beam_grids(fits_header, header_l, header_m, l_axis, m_axis):
    from africanus.util.beams import beam_grids, axis_and_sign

    hdr = fits_header
    hdr['CTYPE1'] = header_l
    hdr['CTYPE2'] = header_m

    l_ax, l_sgn = axis_and_sign(l_axis, "L")
    m_ax, m_sgn = axis_and_sign(m_axis, "M")

    # Extract l, m and frequency axes and grids
    (l, l_grid), (m, m_grid), (freq,
                               freq_grid) = beam_grids(fits_header, l_axis,
                                                       m_axis)

    # Check expected L
    assert hdr['CTYPE%d' % l] == header_l
    crval = hdr['CRVAL%d' % l]
    cdelt = hdr['CDELT%d' % l]
    crpix = hdr['CRPIX%d' % l] - 1  # C-indexing
    R = np.arange(0.0, float(hdr['NAXIS%d' % l]))

    exp_l = (R - crpix) * cdelt + crval
    exp_l = np.deg2rad(exp_l) * l_sgn

    assert_array_almost_equal(exp_l, l_grid)

    assert hdr['CTYPE%d' % m] == header_m
    crval = hdr['CRVAL%d' % m]
    cdelt = hdr['CDELT%d' % m]
    crpix = hdr['CRPIX%d' % m] - 1  # C-indexing
    R = np.arange(0.0, float(hdr['NAXIS%d' % m]))

    exp_m = (R - crpix) * cdelt + crval
    exp_m = np.deg2rad(exp_m) * m_sgn

    assert_array_almost_equal(exp_m, m_grid)

    # GFREQS used for the frequency grid
    gfreqs = [
        fits_header.get('GFREQ%d' % (i + 1))
        for i in range(fits_header['NAXIS3'])
    ]

    assert_array_almost_equal(freq_grid, gfreqs)
예제 #2
0
def test_beam_grids(fits_header):
    from africanus.util.beams import beam_grids

    hdr = fits_header

    # Extract l, m and frequency axes and grids
    (l, l_grid), (m, m_grid), (freq, freq_grid) = beam_grids(fits_header)

    # Check expected L
    crval = hdr['CRVAL%d' % l]
    cdelt = hdr['CDELT%d' % l]
    crpix = hdr['CRPIX%d' % l] - 1  # C-indexing
    R = np.arange(0.0, float(hdr['NAXIS%d' % l]))

    exp_l = (R - crpix) * cdelt + crval
    exp_l = np.deg2rad(exp_l)

    assert np.allclose(exp_l, l_grid)

    crval = hdr['CRVAL%d' % m]
    cdelt = hdr['CDELT%d' % m]
    crpix = hdr['CRPIX%d' % m] - 1  # C-indexing
    R = np.arange(0.0, float(hdr['NAXIS%d' % m]))

    # Check expected M. It's -M in the FITS header
    # so there's a flip in direction here
    exp_m = (R - crpix) * cdelt + crval
    exp_m = np.deg2rad(exp_m)
    exp_m = np.flipud(exp_m)

    assert np.allclose(exp_m, m_grid)

    # GFREQS used for the frequency grid
    gfreqs = [
        fits_header.get('GFREQ%d' % (i + 1))
        for i in range(fits_header['NAXIS3'])
    ]

    assert np.allclose(freq_grid, gfreqs)
예제 #3
0
def load_beams(beam_file_schema, corr_types):

    class FITSFile(object):
        """ Exists so that fits file is closed when last ref is gc'd """

        def __init__(self, filename):
            self.hdul = hdul = fits.open(filename)
            assert len(hdul) == 1
            self.__del_ref = weakref.ref(self, lambda r: hdul.close())

    # Open files and get headers
    beam_files = []
    headers = []

    for corr, (re, im) in beam_filenames(beam_file_schema, corr_types).items():
        re_f = FITSFile(re)
        im_f = FITSFile(im)
        beam_files.append((corr, (re_f, im_f)))
        headers.append((corr, (re_f.hdul[0].header, im_f.hdul[0].header)))

    # All FITS headers should agree
    flat_headers = [d for k, v in headers for d in v]

    if not all(flat_headers[0] == h for h in flat_headers[1:]):
        raise ValueError("BEAM FITS Header Files differ")

    #  Map FITS header type to NumPy type
    BITPIX_MAP = {8: np.dtype('uint8').type, 16: np.dtype('int16').type,
                  32: np.dtype('int32').type, -32: np.dtype('float32').type,
                  -64: np.dtype('float64').type}

    header = flat_headers[0]
    bitpix = header['BITPIX']

    try:
        dtype = BITPIX_MAP[bitpix]
    except KeyError:
        raise ValueError("No mapping from BITPIX %s to a numpy type" % bitpix)
    else:
        dtype = np.result_type(dtype, np.complex64)

    if not header['NAXIS'] == 3:
        raise ValueError("FITS must have exactly three axes. "
                         "L or X, M or Y and FREQ. NAXIS != 3")

    (l_ax, l_grid), (m_ax, m_grid), (nu_ax, nu_grid) = beam_grids(header)

    # Shape of each correlation
    shape = (l_grid.shape[0], m_grid.shape[0], nu_grid.shape[0])

    # Axis tranpose, FITS is FORTRAN ordered
    ax = (nu_ax - 1, m_ax - 1, l_ax - 1)

    def _load_correlation(re, im, ax):
        # Read real and imaginary for each correlation
        return (re.hdul[0].data.transpose(ax) +
                im.hdul[0].data.transpose(ax)*1j)

    # Create delayed loads of the beam
    beam_loader = dask.delayed(_load_correlation)

    beam_corrs = [beam_loader(re, im, ax)
                  for c, (corr, (re, im)) in enumerate(beam_files)]
    beam_corrs = [da.from_delayed(bc, shape=shape, dtype=dtype)
                  for bc in beam_corrs]

    # Stack correlations and rechunk to one great big block
    beam = da.stack(beam_corrs, axis=3)
    beam = beam.rechunk(shape + (len(corr_types),))

    # Dask arrays for the beam extents and beam frequency grid
    beam_lm_ext = np.array([[l_grid[0], l_grid[-1]], [m_grid[0], m_grid[-1]]])
    beam_lm_ext = da.from_array(beam_lm_ext, chunks=beam_lm_ext.shape)
    beam_freq_grid = da.from_array(nu_grid, chunks=nu_grid.shape)

    return beam, beam_lm_ext, beam_freq_grid