pyuvdata icon indicating copy to clipboard operation
pyuvdata copied to clipboard

Add support for feed position angles

Open telegraphic opened this issue 1 year ago • 7 comments

Currently, the UVData object does not support arbitrary feed polarization angles. This would be useful, and UVFITS/MS files already support this (see below). My personal motivation is that the upcoming SKA-Low stations are all rotated at different angles for "polarization diversity" and to improve sidelobe response between antenna pairs.

Currently, when writing to UVFITS the polarization angle keywords are hardcoded. I can't see anything similar for MS, which uses the RECEPTOR_ANGLE keyword -- presumably casacore fills these with default values.

To make this possible, I think the following would have to happen:

  1. An attribute is added to UVData, e.g. UVData.feed_polarization_angle and __init__ is updated accordingly (with (90, 0) degrees as default values).
  2. All writers are updated to use these values.
  3. All readers are updated to read the relevant keywords when creating a UVData object.
  4. Tests are written (roundtrip conversion, e.g. UVData -> UVFITS -> UVData would exercise both read and write).
  5. Documentation is updated.

I don't have enough free cycles to take all this on, but I have some example code for UVFITS + MS below.

UVFITS keywords

From AIPS Memo 117.

In UVFITS, AIPS AN antenna table, the columns POLAA and POLAB should be updated:

POLAA  1E  degrees  Position angle feed A
POLAB  1E  degrees  Position angle feed B

The value of the POLAA column shall be the orientation of feed A, assumed independent of IF, given in degrees. Similarly, the POLAB column shall contain the feed orientation for feed B.

MS keywords

Need to update RECEPTOR_ANGLE column of the FEED table of a measurement set: https://safe.nrao.edu/wiki/bin/view/ALMA/ReceptorAngles

These angles are stored in radians. If there are multiple receiver bands in a measurement set, then multiple angles will be shown.

Miriad

No idea what keywords would need to change.

Proto-code


def write_ms(uv: UVData, filename: str, *args, **kwargs):
    """Write UVData to MeasurementSet.

    Notes:
        Calls uv.write_ms(), then applies station rotation patch.
    Args:
        uv (UVData): pyuvdata object to write to file.
        filename (str): Name of output filename.
        args (list): Arguments to pass to uv.write_ms
        kwargs (dict): Keyword arguments to pass to uv.write_ms
    """
    tables = import_optional_dependency('casacore.tables', errors='raise')

    uv.write_ms(filename, *args, **kwargs)

    # Patch RECEPTOR_ANGLE column
    with tables.table(f'{filename}/FEED', readonly=False) as t:
        logger.debug('Applying station rotation (RECEPTOR_ANGLE)')
        r_ang = np.zeros(shape=t.getcol('RECEPTOR_ANGLE').shape, dtype='float64')
        x_ang = -np.pi/180 * uv.receptor_angle
        r_ang[:, 0] = x_ang
        r_ang[:, 1] = x_ang + np.pi

        t.putcol('RECEPTOR_ANGLE', r_ang)


def write_uvfits(uv: UVData, filename: str, *args, **kwargs):
    """Write UVData to UVFITS.

    Notes:
        Calls uv.write_uvfits(), then applies station rotation patch.
    Args:
        uv (UVData): pyuvdata object to write to file.
        filename (str): Name of output filename.
        args (list): Arguments to pass to uv.write_uvfits
        kwargs (dict): Keyword arguments to pass to uv.write_uvfits
    """
    uv.write_uvfits(filename, *args, **kwargs)

    # Patch POLAA/POLAB columns
    with pf.open(filename, mode='update') as hdu:
        logger.debug('Applying station rotation (POLAA/POLAB)')
        hdu[1].data['POLAA'] = uv.receptor_angle
        hdu[1].data['POLAB'] = uv.receptor_angle + 90

telegraphic avatar Aug 23 '24 12:08 telegraphic

Hey @telegraphic!

Currently, the UVData object does support arbitrary feed polarization angles.

I assume you mean "does not" here, right?

As an aside, this is actually something I'm interested in too for SMA, and was part of the motivation for migrating some things inside of UVData into the new telescope attribute (which is an instantiation of the Telescope class). A question for you -- do you actually have polarimetric data that we could test this with? I've got some SMA data I could potentially test against, but it's nice not to have to solely depend on data from one telescope to verify that things are working as expected...

kartographer avatar Aug 23 '24 12:08 kartographer

An alternate implementation would be to have x_orientation be a float in radians.

steven-murray avatar Aug 23 '24 14:08 steven-murray

Currently, the UVData object does support arbitrary feed polarization angles.

I assume you mean "does not" here, right?

Ah, yes indeed!

We don't have data to test against yet, but will eventually, and we need to figure out if we're handling the polarization correctly so we can combine stations. I might be able to get some ALMA data from Shinichiro on a shorter timescale -- will investigate

telegraphic avatar Aug 24 '24 15:08 telegraphic

Just noting that I think this is related to issue #854, although this issue may be more developed.

@steven-murray

An alternate implementation would be to have x_orientation be a float in radians.

I think the request goes beyond this, I think it needs to be a vector of length Nants_telescope.

bhazelton avatar Aug 27 '24 22:08 bhazelton

Ah yes you are totally correct!

steven-murray avatar Aug 28 '24 10:08 steven-murray

Does Alma have arbitrary pol? I thought they were fixed in alt,az. Wouldn’t aska, with its rotating dishes, be a better test? Am I remembering wrong?

On Wed, Aug 28, 2024 at 3:40 AM Steven Murray @.***> wrote:

Ah yes you are totally correct!

— Reply to this email directly, view it on GitHub https://github.com/RadioAstronomySoftwareGroup/pyuvdata/issues/1470#issuecomment-2314959055, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAPNV7RLI3UNSMMWU6HBADZTWSKZAVCNFSM6AAAAABNABO6VKVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDGMJUHE2TSMBVGU . You are receiving this because you are subscribed to this thread.Message ID: @.*** com>

-- Sent from Gmail Mobile

dannyjacobs avatar Aug 28 '24 16:08 dannyjacobs

We talked about this in the telecon today, it's on @kartographer's agenda sometime soonish. CASA implements these with an optional time axis while UVFITS does not support a time axis. We also realized that the mount type column in UVFITS (mntsta) is being set incorrectly. It is hardcoded to zero but for HERA and MWA it should be 6.

bhazelton avatar Sep 17 '24 15:09 bhazelton