Beispiel #1
0
def cvcimage(cvcobj,
             filestep,
             cubeslice,
             req_calsrc=None,
             docalibrate=True,
             pbcor=False):
    """Image a CVC object.

    Parameters
    ----------

    cvcobj : CVCfiles()
        The covariance cube files object containing visibility cubes.
    filestep : int
        The file index to select.
    cubeslice : int
        The cube index in file.
    req_calsrc : str
        The requested sky source.
    docalibrate : bool
        Perform calibration or not.
    pbcor : bool
        Perform primary beam correction or not.

    Returns
    -------

    ll : array
        The l-direction cosine map.
    mm : array
        The m-direction cosine map.
    images : tuple
        Tuple of polarized image maps.
    polrep : str
        Polarization representation of the images tuple.
    t : datetime
        Observation time.
    freq : float
        Observation frequency.
    stnid : str
        Station id.
    phaseref : tuple
        Direction of phase reference used for imaging.

    """
    t = cvcobj.samptimeset[filestep][cubeslice]
    freq = cvcobj.freqset[filestep][cubeslice]
    cvcdata_unc = cvcobj.getdata(filestep)

    stnid = cvcobj.stnsesinfo.get_stnid()
    bandarr = cvcobj.stnsesinfo.get_bandarr()
    band = cvcobj.stnsesinfo.get_band()
    rcumode = cvcobj.stnsesinfo.get_rcumode()
    pointingstr = cvcobj.stnsesinfo.get_pointingstr()

    # Get/Compute ant positions
    stnPos, stnRot, antpos, stnIntilePos \
                            = antennafieldlib.getArrayBandParams(stnid, bandarr)
    septon = cvcobj.stnsesinfo.is_septon()
    if septon:
        elmap = cvcobj.stnsesinfo.get_septon_elmap()
        for tile, elem in enumerate(elmap):
            antpos[tile] = antpos[tile] + stnIntilePos[elem]

    # stn2Dcoord = stnRot.T * antpos.T
    # Apply calibration
    datatype = cvcobj.stnsesinfo.get_datatype()
    if datatype == 'acc':
        cvcdata, caltabhead = calibrationtables.calibrateACC(
            cvcdata_unc, rcumode, stnid, t, docalibrate)
    else:
        sb, nz = modeparms.freq2sb(freq)
        cvcdata, caltabhead = calibrationtables.calibrateXST(
            cvcdata_unc, sb, rcumode, stnid, t, docalibrate)
    cvpol = dataIO.cvc2cvpol(cvcdata)

    # Determine if allsky FoV
    if band == '10_90' or band == '30_90' or septon:
        allsky = True
    else:
        allsky = False

    # Determine phaseref
    if req_calsrc is not None:
        pntstr = ilisa.observations.directions.std_pointings(req_calsrc)
    elif allsky:
        pntstr = ilisa.observations.directions.std_pointings('Z')
    else:
        pntstr = pointingstr
    phaseref = pntstr.split(',')

    skyimage = True
    if skyimage:
        # Phase up visibilities
        cvpu, UVWxyz = phaseref_xstpol(cvpol[:, :, cubeslice, ...].squeeze(),
                                       t, freq, stnPos, antpos, phaseref)

        # Make image on phased up visibilities
        polrep, images, ll, mm = xst2skyim_stn2Dcoord(cvpu,
                                                      UVWxyz.T,
                                                      freq,
                                                      include_autocorr=False,
                                                      allsky=allsky,
                                                      polrep_req='XY')
        if pbcor and canuse_dreambeam:
            # Get dreambeam jones:
            pointing = (float(phaseref[0]), float(phaseref[1]), 'STN')
            jonesfld, stnbasis, j2000basis = primarybeampat('LOFAR',
                                                            stnid,
                                                            bandarr,
                                                            'Hamaker',
                                                            freq,
                                                            pointing=pointing,
                                                            obstime=t,
                                                            lmgrid=(ll, mm))
            ijones = numpy.linalg.inv(jonesfld)
            bri_ant = numpy.array([[images[0], images[1]],
                                   [images[2], images[3]]])

            bri_ant = numpy.moveaxis(numpy.moveaxis(bri_ant, 0, -1), 0, -1)

            ijonesH = numpy.conj(numpy.swapaxes(ijones, -1, -2))
            bri_xy_iau = numpy.matmul(numpy.matmul(ijones, bri_ant), ijonesH)
            images = (bri_xy_iau[:, :, 0, 0], bri_xy_iau[:, :, 0, 1],
                      bri_xy_iau[:, :, 1, 0], bri_xy_iau[:, :, 1, 1])
        if canuse_stokes and polrep == 'XY':
            images = convertxy2stokes(images[0], images[1], images[2],
                                      images[3])
            polrep = 'Stokes'
    else:
        vis_S0 = cvpol[0, 0, cubeslice, ...].squeeze() + cvpol[0, 0, cubeslice,
                                                               ...].squeeze()
        nfhimages, ll, mm = nearfield_grd_image(vis_S0,
                                                antpos,
                                                freq,
                                                include_autocorr=True)
        polrep = 'S0'
        images = numpy.real(nfhimages)

    return ll, mm, images, polrep, t, freq, stnid, phaseref
Beispiel #2
0
def cvc_image(cvcobj, filestep, cubeslice, req_calsrc=None, pbcor=False,
              fluxperbeam=True, polrep='stokes'):
    """
    Image CVC object using beamformed synthesis

    Parameters
    ----------
    cvcobj : CVCfiles()
        The covariance cube files object containing visibility cubes.
    filestep : int
        The file index to select.
    cubeslice : int
        The cube index in file.
    req_calsrc : str
        The requested sky source.
    pbcor : bool
        Perform primary beam correction or not.
    polrep : str
        Polarization representation to use for image.

    Returns
    -------
    ll : array
        The l-direction cosine map.
    mm : array
        The m-direction cosine map.
    images : tuple
        Tuple of polarized image maps.
    t : datetime
        Observation time.
    freq : float
        Observation frequency.
    phaseref : tuple
        Direction of phase reference used for imaging.
    """
    t = cvcobj.samptimeset[filestep][cubeslice]
    freq = cvcobj.freqset[filestep][cubeslice]

    pointingstr = cvcobj.scanrecinfo.get_pointingstr()
    stn_pos = cvcobj.stn_pos
    stn_antpos = cvcobj.stn_antpos

    cvcpol_lin = dataIO.cvc2polrep(cvcobj[filestep], crlpolrep='lin')

    allsky = cvcobj.scanrecinfo.get_allsky()
    phaseref = _req_calsrc_proc(req_calsrc, allsky, pointingstr)

    # Select a visibility snapshot
    cvpol_lin = cvcpol_lin[:, :, cubeslice, ...].squeeze()

    # Calculate UVW coords
    UVWxyz = calc_uvw(t, phaseref, stn_pos, stn_antpos)

    # Phase up visibilities
    cvpu_lin = phaseref_xstpol(cvpol_lin, UVWxyz, freq)

    # Determine FoV and image lm size
    bandarr = cvcobj.scanrecinfo.get_bandarr()
    lmsize = 2.0
    if not allsky:
        d = antennafieldlib.ELEMENT_DIAMETER[bandarr]
        fov = 2*airydisk_radius(freq, d)
        lmsize = 1.0*fov

    # Make image on phased up visibilities
    imgs_lin, ll, mm = beamformed_image(
        cvpu_lin, UVWxyz.T, freq, use_autocorr=False, lmsize=lmsize,
        polrep='linear', fluxperbeam=fluxperbeam)

    # Potentially apply primary beam correction 
    if pbcor and CANUSE_DREAMBEAM:
        # Get dreambeam jones:
        pointing = (float(phaseref[0]), float(phaseref[1]), 'STN')
        stnid = cvcobj.scanrecinfo.get_stnid()
        jonesfld, _stnbasis, _j2000basis = primarybeampat(
            'LOFAR', stnid, bandarr, 'Hamaker', freq, pointing=pointing,
            obstime=t, lmgrid=(ll, mm))
        ijones = numpy.linalg.inv(jonesfld)
        bri_ant = numpy.array([[imgs_lin[0], imgs_lin[1]],
                               [imgs_lin[2], imgs_lin[3]]])

        bri_ant = numpy.moveaxis(numpy.moveaxis(bri_ant, 0, -1), 0, -1)

        ijonesH = numpy.conj(numpy.swapaxes(ijones, -1, -2))
        bri_xy_iau = numpy.matmul(numpy.matmul(ijones, bri_ant), ijonesH)
        imgs_lin = (bri_xy_iau[:, :, 0, 0], bri_xy_iau[:, :, 0, 1],
                    bri_xy_iau[:, :, 1, 0], bri_xy_iau[:, :, 1, 1])
    
    # Convert to requested polarization representation
    if polrep == 'stokes' and CANUSE_DREAMBEAM:
        images = convertxy2stokes(imgs_lin[0], imgs_lin[1], imgs_lin[2],
                                  imgs_lin[3])
    elif polrep == 'circular' and CANUSE_DREAMBEAM:
        imgpolmat_lin = numpy.array([[imgs_lin[0], imgs_lin[1]],
                                     [imgs_lin[2], imgs_lin[3]]])
        imgpolmat = cov_lin2cir(imgpolmat_lin)
        images = (imgpolmat[0][0], imgpolmat[0][1], imgpolmat[1][0],
                  imgpolmat[1][1])
    else:
        # polrep == 'linear'
        images = imgs_lin

    return images, ll, mm, phaseref
Beispiel #3
0
def xst2skyim_stn2Dcoord(xstpol,
                         stn2Dcoord,
                         freq,
                         include_autocorr=True,
                         allsky=False,
                         polrep_req='Stokes'):
    """Image XSTpol data.

    Parameters
    ----------

    xstpol : array
        The crosslet statistics data.
    stn2Dcoord: array
        The 2D array configuration matrix.
    freq : float
        The frequency of the the data in Hz.
    include_autocorr : bool
        Whether or not to include the autocorrelations.
    allsky : bool
        Should an allsky image be produced?
    polrep_req : str
        Requested type of representation for the polarimetric data.
        Can be 'Stokes' or 'XY'. (If dreamBeam package not accessible only 'XY' is
        possible)

    Returns
    -------

    polrep : str
        The polarization representation of the image tuple.
        Can be 'Stokes' or 'XY'.
    (skyimag_0, skyimag_1, skyimag_2, skyimag_3): tuple
        Polarimetric image maps.
        If polrep='Stokes' (and dreamBeam package accessible) then the elements
        correspond to Stokes I,Q,U,V.
        If  polrep='XY' then the elements correspond to XX,XY,YX,YY.
    ll : array
        The l direction cosine of the image.
    mm : array
        The m direction cosine of the image.

    """
    if not include_autocorr:
        for indi in range(2):
            for indj in range(2):
                numpy.fill_diagonal(xstpol[indi, indj, :, :], 0.0)
    posU, posV = stn2Dcoord[0, :].squeeze(), stn2Dcoord[1, :].squeeze()
    lambda0 = c / freq
    k = 2 * numpy.pi / lambda0
    if not allsky:
        lmext = fov(freq)
    else:
        lmext = 1.0
    nrpix = 101
    l, m = numpy.linspace(-lmext, lmext,
                          nrpix), numpy.linspace(-lmext, lmext, nrpix)
    ll, mm = numpy.meshgrid(l, m)
    bf = numpy.exp(-1.j * k * (numpy.einsum('ij,k->ijk', ll, posU) +
                               numpy.einsum('ij,k->ijk', mm, posV)))
    bfbf = numpy.einsum('ijk,ijl->ijkl', bf, numpy.conj(bf))
    skyimag_xx = numpy.einsum('ijkl,kl->ij', bfbf, xstpol[0, 0, ...].squeeze())
    skyimag_xy = numpy.einsum('ijkl,kl->ij', bfbf, xstpol[0, 1, ...].squeeze())
    skyimag_yx = numpy.einsum('ijkl,kl->ij', bfbf, xstpol[1, 0, ...].squeeze())
    skyimag_yy = numpy.einsum('ijkl,kl->ij', bfbf, xstpol[1, 1, ...].squeeze())
    if polrep_req == 'Stokes' and canuse_stokes:
        skyimag_si, skyimag_sq, skyimag_su, skyimag_sv = convertxy2stokes(
            skyimag_xx, skyimag_xy, skyimag_yx, skyimag_yy)
        polrep = 'Stokes'
        return polrep, (skyimag_si, skyimag_sq, skyimag_su, skyimag_sv), ll, mm
    else:
        polrep = 'XY'
        return polrep, (skyimag_xx, skyimag_xy, skyimag_yx, skyimag_yy), ll, mm
Beispiel #4
0
def beamformed_image(xstpol, stn2Dcoord, freq, use_autocorr=True,
                     lmsize=2.0, polrep='linear', fluxperbeam=True):
    """
    Beamformed image XSTpol data.

    Parameters
    ----------
    xstpol : array
        The crosslet statistics data. Should have format:
        xstpol[polport1, polport2, elemnr1, elemnr2] where polport1 and
        polport2 are the two polarization ports, e.g. X and Y, and elemnr1 and
        elemnr2 are two elements of the interferometer array configuration.
    stn2Dcoord : array
        The 2D array configuration matrix.
    freq : float
        The frequency of the the data in Hz.
    use_autocorr : bool
        Whether or not to include the autocorrelations.
    lmsize : float
        Size of image in (lm) direction-cosine units. Default 2.0 means allsky.
    polrep : str
        Requested type of representation for the polarimetric data.
        Can be 'linear' (default), 'circular', or 'stokes'.
        (If dreamBeam package not accessible only 'linear' is possible)
    fluxperbeam : bool
        If True, then the flux is per beam, else the flux is per sterradian.

    Returns
    -------
    (skyimag_0, skyimag_1, skyimag_2, skyimag_3) : tuple
        Polarimetric image maps.
        If polrep='Stokes' (and dreamBeam package accessible) then the elements
        correspond to Stokes I,Q,U,V.
        If  polrep='XY' then the elements correspond to XX,XY,YX,YY.
    ll : array
        The l direction cosine of the image.
    mm : array
        The m direction cosine of the image.

    """
    if not use_autocorr:
        # Set Autocorrelations to zero:
        xstpol = numpy.copy(xstpol)  # Copy since diagonal will be rewritten
        for indi in range(2):
            for indj in range(2):
                numpy.fill_diagonal(xstpol[indi, indj, :, :], 0.0)
    posU, posV = stn2Dcoord[0, :].squeeze(), stn2Dcoord[1, :].squeeze()
    lambda0 = sys.float_info.max
    if freq != 0.0:
        lambda0 = c / freq
    k = 2 * numpy.pi / lambda0
    lmext = lmsize/2.0
    nrpix = 101
    l, m = numpy.linspace(-lmext, lmext, nrpix), numpy.linspace(-lmext, lmext,
                                                                nrpix)
    ll, mm = numpy.meshgrid(l, m)
    bf = numpy.exp(-1.j*k*(numpy.einsum('ij,k->ijk', ll, posU)
                           + numpy.einsum('ij,k->ijk', mm, posV)))
    bfbf = numpy.einsum('ijk,ijl->ijkl', bf, numpy.conj(bf))
    skyimag_xx = numpy.einsum('ijkl,kl->ij', bfbf, xstpol[0, 0, ...].squeeze())
    skyimag_xy = numpy.einsum('ijkl,kl->ij', bfbf, xstpol[0, 1, ...].squeeze())
    skyimag_yx = numpy.einsum('ijkl,kl->ij', bfbf, xstpol[1, 0, ...].squeeze())
    skyimag_yy = numpy.einsum('ijkl,kl->ij', bfbf, xstpol[1, 1, ...].squeeze())
    if not fluxperbeam:
        ll2mm2 = ll**2+mm**2
        beyond_horizon = ll2mm2 >= 1.0
        nn = numpy.sqrt(1-ll2mm2.astype('complex'))
        # Weight values beyond horizon to zero
        nn[beyond_horizon] = 0.0
        skyimag_xx = skyimag_xx * nn
        skyimag_xy = skyimag_xy * nn
        skyimag_yx = skyimag_yx * nn
        skyimag_yy = skyimag_yy * nn
    (skyimag_0, skyimag_1, skyimag_2, skyimag_3) = (None, None, None, None)
    if not CANUSE_DREAMBEAM or polrep == 'linear':
        (skyimag_0, skyimag_1, skyimag_2, skyimag_3) =\
            (skyimag_xx, skyimag_xy, skyimag_yx, skyimag_yy)
    elif polrep == 'stokes':
        skyimag_si, skyimag_sq, skyimag_su, skyimag_sv = convertxy2stokes(
                            skyimag_xx, skyimag_xy, skyimag_yx, skyimag_yy)
        (skyimag_0, skyimag_1, skyimag_2, skyimag_3) =\
                            (skyimag_si, skyimag_sq, skyimag_su, skyimag_sv)
    elif polrep == 'circular':
        skyimag_circ = cov_lin2cir([[skyimag_xx, skyimag_xy],
                                    [skyimag_yx, skyimag_yy]])
        skyimag_0 = skyimag_circ[0][0]
        skyimag_1 = skyimag_circ[0][1]
        skyimag_2 = skyimag_circ[1][0]
        skyimag_3 = skyimag_circ[1][1]
    return (skyimag_0, skyimag_1, skyimag_2, skyimag_3), ll, mm